1#[cfg(test)]
24mod tests;
25
26use std::convert::TryInto;
27use std::mem;
28
29use crate::error::Error;
30use crate::take_bytes::TakeBytes;
31
32pub trait FromBytes
36where
37 Self: Sized,
38{
39 fn from_bytes<TB: TakeBytes>(source: &mut TB) -> Result<Self, Error>;
51}
52
53impl FromBytes for bool {
54 fn from_bytes<TB: TakeBytes>(source: &mut TB) -> Result<Self, Error> {
55 let val: u8 = FromBytes::from_bytes(source)?;
56
57 Ok(val != 0)
58 }
59}
60
61macro_rules! impl_from_bytes_for_primitive {
62 ($type:ty) => {
63 impl FromBytes for $type {
64 fn from_bytes<TB: TakeBytes>(source: &mut TB) -> Result<Self, Error> {
65 let mut buf = [0; mem::size_of::<$type>()];
66
67 source.take_bytes(&mut buf)?;
68
69 Ok(<$type>::from_be_bytes(buf))
70 }
71 }
72 };
73}
74
75impl_from_bytes_for_primitive!(i8);
76impl_from_bytes_for_primitive!(i16);
77impl_from_bytes_for_primitive!(i32);
78impl_from_bytes_for_primitive!(i64);
79impl_from_bytes_for_primitive!(u8);
80impl_from_bytes_for_primitive!(u16);
81impl_from_bytes_for_primitive!(u32);
82impl_from_bytes_for_primitive!(u64);
83impl_from_bytes_for_primitive!(f32);
84impl_from_bytes_for_primitive!(f64);
85
86impl FromBytes for usize {
87 fn from_bytes<TB: TakeBytes>(source: &mut TB) -> Result<Self, Error> {
88 let mut buf = [0; mem::size_of::<u64>()];
89
90 source.take_bytes(&mut buf)?;
91
92 Ok(u64::from_be_bytes(buf) as usize)
93 }
94}
95
96impl FromBytes for char {
97 fn from_bytes<TB: TakeBytes>(source: &mut TB) -> Result<Self, Error> {
98 let n: u32 = FromBytes::from_bytes(source)?;
99
100 char::from_u32(n).ok_or_else(|| Error::InvalidChar(n))
101 }
102}
103
104impl<FB: FromBytes, const COUNT: usize> FromBytes for [FB; COUNT] {
105 fn from_bytes<TB: TakeBytes>(source: &mut TB) -> Result<Self, Error> {
106 let mut vec = vec![];
107
108 for _i in 0..COUNT {
109 vec.push(FromBytes::from_bytes(source)?);
110 }
111
112 Ok(vec
113 .try_into()
114 .unwrap_or_else(|_| panic!("should never be reached")))
115 }
116}
117
118impl<FB: FromBytes> FromBytes for Vec<FB> {
119 fn from_bytes<TB: TakeBytes>(source: &mut TB) -> Result<Self, Error> {
120 let len = usize::from_bytes(source)?;
121 let mut vec = Vec::with_capacity(len);
122
123 for _ in 0..len {
124 vec.push(FromBytes::from_bytes(source)?);
125 }
126
127 Ok(vec)
128 }
129}
130
131impl FromBytes for String {
132 fn from_bytes<TB: TakeBytes>(source: &mut TB) -> Result<Self, Error> {
133 let len = usize::from_bytes(source)?;
134
135 let mut vec = vec![0; len];
136 source.take_bytes(&mut vec)?;
137
138 String::from_utf8(vec).map_err(Error::InvalidString)
139 }
140}
141
142impl<T: FromBytes> FromBytes for Option<T> {
143 fn from_bytes<TB: TakeBytes>(source: &mut TB) -> Result<Self, Error> {
144 let n: u8 = FromBytes::from_bytes(source)?;
145
146 if n == 0 {
147 Ok(None)
148 } else {
149 Ok(Some(FromBytes::from_bytes(source)?))
150 }
151 }
152}
153
154impl FromBytes for () {
155 fn from_bytes<TB: TakeBytes>(_source: &mut TB) -> Result<Self, Error> {
156 Ok(())
157 }
158}