1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use std::io;
use std::io::Read;
use std::marker::PhantomData;

use crate::read_types::ReadType;

pub mod read_types {
    use std::io;
    use std::io::Read;

    use byteorder::{BE, LE, ReadBytesExt};

    pub trait ReadType {
        type NumType;

        fn read_num<R: Read>(reader: &mut R) -> io::Result<Self::NumType>;
    }

    macro_rules! struct_def {
        ($($name:tt $fn_name:tt $ty:ty),+ $(,)?) => {
            $(
                pub struct $name;

                impl ReadType for $name {
                    type NumType = $ty;

                    #[inline(always)]
                    fn read_num<R: Read>(reader: &mut R) -> io::Result<Self::NumType> {
                        reader.$fn_name()
                    }
                }
            )*
        };
        ($($name:tt $fn_name:tt $endianness:tt $ty:ty),+ $(,)?) => {
            $(
                pub struct $name;

                impl ReadType for $name {
                    type NumType = $ty;

                    #[inline(always)]
                    fn read_num<R: Read>(reader: &mut R) -> io::Result<Self::NumType> {
                        reader.$fn_name::<$endianness>()
                    }
                }
            )*
        };
    }

    struct_def!(S8 read_i8 i8);
    struct_def!(
        S16LE read_i16 LE i16,
        S16BE read_i16 BE i16,
        S32LE read_i32 LE i32,
        S32BE read_i32 BE i32,
        F32LE read_f32 LE f32,
        F32BE read_f32 BE f32,
    );
}

pub struct NumberReader<R: Read, T: ReadType> {
    inner: R,
    phantom: PhantomData<T>,
}

impl<R: Read, T: ReadType> NumberReader<R, T> {
    pub fn new(reader: R) -> Self {
        Self {
            inner: reader,
            phantom: Default::default(),
        }
    }
}

impl<R: Read, T: ReadType> Iterator for NumberReader<R, T> {
    type Item = io::Result<T::NumType>;

    fn next(&mut self) -> Option<Self::Item> {
        let result = T::read_num(&mut self.inner);
        match result {
            Ok(r) => Some(Ok(r)),
            Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => None,
            Err(e) => Some(Err(e)),
        }
    }
}

#[cfg(test)]
pub mod test {
    use std::io::Cursor;

    use byteorder::{BE, ByteOrder, LE};

    use crate::NumberReader;
    use crate::read_types;

    #[test]
    fn test1() {
        let data = [1_u8, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        let mut cursor = Cursor::new(data);
        let mut reader = NumberReader::<_, read_types::S32BE>::new(&mut cursor);
        assert_eq!(
            reader.next().map(Result::unwrap),
            Some(BE::read_i32(&[1, 2, 3, 4]))
        );
        assert_eq!(
            reader.next().map(Result::unwrap),
            Some(BE::read_i32(&[5, 6, 7, 8]))
        );
        assert_eq!(reader.next().map(Result::unwrap), None);
    }

    #[test]
    fn test2() {
        let data = [1_u8, 2, 3, 4, 5, 6];
        let mut cursor = Cursor::new(data);
        let mut reader = NumberReader::<_, read_types::S16LE>::new(&mut cursor);
        assert_eq!(
            reader.next().map(Result::unwrap),
            Some(LE::read_i16(&[1, 2]))
        );
        assert_eq!(
            reader.next().map(Result::unwrap),
            Some(LE::read_i16(&[3, 4]))
        );
        assert_eq!(
            reader.next().map(Result::unwrap),
            Some(LE::read_i16(&[5, 6]))
        );
        assert_eq!(reader.next().map(Result::unwrap), None);
    }
}