bytestruct/
lib.rs

1#![feature(array_try_from_fn)]
2use std::{array, io::{self, Read}};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
5pub struct U8(pub u8);
6#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub struct LittleEndianU16(pub u16);
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub struct BigEndianU16(pub u16);
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub struct LittleEndianU32(pub u32);
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
13pub struct BigEndianU32(pub u32);
14#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub struct LittleEndianU64(pub u64);
16#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
17pub struct BigEndianU64(pub u64);
18#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub struct LittleEndianI16(pub i16);
20#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
21pub struct BigEndianI16(pub i16);
22#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
23pub struct LittleEndianI32(pub i32);
24#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
25pub struct BigEndianI32(pub i32);
26#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
27pub struct LittleEndianI64(pub i64);
28#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
29pub struct BigEndianI64(pub i64);
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
32pub struct Array<T, const SIZE: usize>(pub [T; SIZE]);
33
34#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
35pub struct NullTerminatedString<const SIZE: usize>(pub String);
36
37pub type ByteArray<const T: usize> = Array<U8, T>;
38pub type UUID = ByteArray<16>;
39
40pub trait ReadFrom<T: Read> {
41    fn read_from(source: &mut T) -> io::Result<Self> where Self: Sized;
42}
43
44impl<T: Read> ReadFrom<T> for U8 {
45    fn read_from(source: &mut T) -> io::Result<Self> {
46        let mut buf = [0u8; 1];
47        source.read_exact(&mut buf)?;
48        Ok(U8(buf[0]))
49    }
50}
51
52impl<T: Read> ReadFrom<T> for LittleEndianU16 {
53    fn read_from(source: &mut T) -> io::Result<Self> {
54        let mut buf = [0u8; 2];
55        source.read_exact(&mut buf)?;
56        Ok(LittleEndianU16(u16::from_le_bytes(buf)))
57    }
58}
59
60impl<T: Read> ReadFrom<T> for BigEndianU16 {
61    fn read_from(source: &mut T) -> io::Result<Self> {
62        let mut buf = [0u8; 2];
63        source.read_exact(&mut buf)?;
64        Ok(BigEndianU16(u16::from_be_bytes(buf)))
65    }
66}
67
68impl<T: Read> ReadFrom<T> for LittleEndianU32 {
69    fn read_from(source: &mut T) -> io::Result<Self> {
70        let mut buf = [0u8; 4];
71        source.read_exact(&mut buf)?;
72        Ok(LittleEndianU32(u32::from_le_bytes(buf)))
73    }
74}
75
76impl<T: Read> ReadFrom<T> for BigEndianU32 {
77    fn read_from(source: &mut T) -> io::Result<Self> {
78        let mut buf = [0u8; 4];
79        source.read_exact(&mut buf)?;
80        Ok(BigEndianU32(u32::from_be_bytes(buf)))
81    }
82}
83
84impl<T: Read> ReadFrom<T> for LittleEndianU64 {
85    fn read_from(source: &mut T) -> io::Result<Self> {
86        let mut buf = [0u8; 8];
87        source.read_exact(&mut buf)?;
88        Ok(LittleEndianU64(u64::from_le_bytes(buf)))
89    }
90}
91
92impl<T: Read> ReadFrom<T> for BigEndianU64 {
93    fn read_from(source: &mut T) -> io::Result<Self> {
94        let mut buf = [0u8; 8];
95        source.read_exact(&mut buf)?;
96        Ok(BigEndianU64(u64::from_be_bytes(buf)))
97    }
98}
99
100impl<T: Read> ReadFrom<T> for LittleEndianI16 {
101    fn read_from(source: &mut T) -> io::Result<Self> {
102        let mut buf = [0u8; 2];
103        source.read_exact(&mut buf)?;
104        Ok(LittleEndianI16(i16::from_le_bytes(buf)))
105    }
106}
107
108impl<T: Read> ReadFrom<T> for BigEndianI16 {
109    fn read_from(source: &mut T) -> io::Result<Self> {
110        let mut buf = [0u8; 2];
111        source.read_exact(&mut buf)?;
112        Ok(BigEndianI16(i16::from_be_bytes(buf)))
113    }
114}
115
116impl<T: Read> ReadFrom<T> for LittleEndianI32 {
117    fn read_from(source: &mut T) -> io::Result<Self> {
118        let mut buf = [0u8; 4];
119        source.read_exact(&mut buf)?;
120        Ok(LittleEndianI32(i32::from_le_bytes(buf)))
121    }
122}
123
124impl<T: Read> ReadFrom<T> for BigEndianI32 {
125    fn read_from(source: &mut T) -> io::Result<Self> {
126        let mut buf = [0u8; 4];
127        source.read_exact(&mut buf)?;
128        Ok(BigEndianI32(i32::from_be_bytes(buf)))
129    }
130}
131
132impl<T: Read> ReadFrom<T> for LittleEndianI64 {
133    fn read_from(source: &mut T) -> io::Result<Self> {
134        let mut buf = [0u8; 8];
135        source.read_exact(&mut buf)?;
136        Ok(LittleEndianI64(i64::from_le_bytes(buf)))
137    }
138}
139
140impl<T: Read> ReadFrom<T> for BigEndianI64 {
141    fn read_from(source: &mut T) -> io::Result<Self> {
142        let mut buf = [0u8; 8];
143        source.read_exact(&mut buf)?;
144        Ok(BigEndianI64(i64::from_be_bytes(buf)))
145    }
146}
147
148impl <const SIZE: usize, T: Read> ReadFrom<T> for NullTerminatedString<SIZE> {
149    fn read_from(source: &mut T) -> io::Result<Self> {
150        let mut buf = [0u8; SIZE];
151        source.read_exact(&mut buf)?;
152        let mut len = 0;
153        for i in 0..SIZE {
154            if buf[i] == 0 {
155                break;
156            }
157            len += 1;
158        }
159
160        if len == SIZE {
161            return Err(io::Error::new(io::ErrorKind::InvalidData, "String is not null terminated"));
162        }
163
164        Ok(NullTerminatedString(String::from_utf8_lossy(&buf[..len]).to_string()))
165    }
166}
167
168impl <const SIZE: usize, R: Read, T: ReadFrom<R>> ReadFrom<R> for Array<T, SIZE> {
169    fn read_from(source: &mut R) -> io::Result<Self> {
170        Ok(Array(array::try_from_fn(|_| T::read_from(source))?))
171    }
172}