Skip to main content

steel_utils/serial/
prefixed_read.rs

1use 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}