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}