steel_utils/serial/
prefixed_read.rs1use std::io::{Cursor, Error, Read, Result};
2
3use crate::serial::{PrefixedRead, ReadFrom};
4
5impl PrefixedRead for String {
6 fn read_prefixed_bound<P: TryInto<usize> + ReadFrom>(
7 data: &mut Cursor<&[u8]>,
8 bound: usize,
9 ) -> Result<Self> {
10 let len: usize = P::read(data)?
11 .try_into()
12 .map_err(|_| Error::other("Invalid Prefix"))?;
13
14 if len > bound {
15 Err(Error::other("To long"))?;
16 }
17
18 let mut buf = vec![0; len];
19 data.read_exact(&mut buf)?;
20 String::from_utf8(buf).map_err(Error::other)
21 }
22}
23
24impl<T: ReadFrom> PrefixedRead for Vec<T> {
25 fn read_prefixed_bound<P: TryInto<usize> + ReadFrom>(
26 data: &mut Cursor<&[u8]>,
27 bound: usize,
28 ) -> Result<Self> {
29 let len: usize = P::read(data)?
30 .try_into()
31 .map_err(|_| Error::other("Invalid Prefix"))?;
32
33 if len > bound {
34 Err(Error::other("To long"))?;
35 }
36 let mut items = Vec::with_capacity(len);
37 for _ in 0..len {
38 items.push(T::read(data)?);
39 }
40 Ok(items)
41 }
42}
43
44impl<T: PrefixedRead> PrefixedRead for Option<T> {
45 fn read_prefixed_bound<P: TryInto<usize> + ReadFrom>(
46 data: &mut Cursor<&[u8]>,
47 bound: usize,
48 ) -> Result<Self> {
49 if bool::read(data)? {
50 Ok(Some(T::read_prefixed_bound::<P>(data, bound)?))
51 } else {
52 Ok(None)
53 }
54 }
55}