Skip to main content

steel_utils/serial/
prefixed_write.rs

1use std::io::{Error, Result, Write};
2
3use crate::serial::{PrefixedWrite, WriteTo};
4
5impl PrefixedWrite for String {
6    fn write_prefixed_bound<P: TryFrom<usize> + WriteTo>(
7        &self,
8        writer: &mut impl Write,
9        bound: usize,
10    ) -> Result<()> {
11        if self.len() > bound {
12            Err(Error::other("Too long"))?;
13        }
14
15        let len: P = self
16            .len()
17            .try_into()
18            .map_err(|_| Error::other("This cant happen"))?;
19        len.write(writer)?;
20
21        writer.write_all(self.as_bytes())
22    }
23}
24
25impl PrefixedWrite for str {
26    fn write_prefixed_bound<P: TryFrom<usize> + WriteTo>(
27        &self,
28        writer: &mut impl Write,
29        bound: usize,
30    ) -> Result<()> {
31        if self.len() > bound {
32            Err(Error::other("Too long"))?;
33        }
34
35        let len: P = self
36            .len()
37            .try_into()
38            .map_err(|_| Error::other("This cant happen"))?;
39        len.write(writer)?;
40
41        writer.write_all(self.as_bytes())
42    }
43}
44
45impl<T: WriteTo> PrefixedWrite for Vec<T> {
46    fn write_prefixed_bound<P: TryFrom<usize> + WriteTo>(
47        &self,
48        writer: &mut impl Write,
49        bound: usize,
50    ) -> Result<()> {
51        if self.len() > bound {
52            Err(Error::other("Too long"))?;
53        }
54
55        let len: P = self
56            .len()
57            .try_into()
58            .map_err(|_| Error::other("This cant happen"))?;
59
60        len.write(writer)?;
61
62        for property in self {
63            property.write(writer)?;
64        }
65
66        Ok(())
67    }
68}
69
70impl<T: WriteTo> PrefixedWrite for [T] {
71    fn write_prefixed_bound<P: TryFrom<usize> + WriteTo>(
72        &self,
73        writer: &mut impl Write,
74        bound: usize,
75    ) -> Result<()> {
76        if self.len() > bound {
77            Err(Error::other("Too long"))?;
78        }
79
80        let len: P = self
81            .len()
82            .try_into()
83            .map_err(|_| Error::other("This cant happen"))?;
84
85        len.write(writer)?;
86
87        for property in self {
88            property.write(writer)?;
89        }
90
91        Ok(())
92    }
93}
94
95impl<T: WriteTo, const N: usize> PrefixedWrite for [T; N] {
96    fn write_prefixed_bound<P: TryFrom<usize> + WriteTo>(
97        &self,
98        writer: &mut impl Write,
99        bound: usize,
100    ) -> Result<()> {
101        if N > bound {
102            Err(Error::other("Too long"))?;
103        }
104
105        P::try_from(N)
106            .map_err(|_| Error::other("This cant happen"))?
107            .write(writer)?;
108
109        for i in self {
110            i.write(writer)?;
111        }
112        Ok(())
113    }
114}
115
116impl<T: PrefixedWrite> PrefixedWrite for Option<T> {
117    fn write_prefixed_bound<P: TryFrom<usize> + WriteTo>(
118        &self,
119        writer: &mut impl Write,
120        bound: usize,
121    ) -> Result<()> {
122        if let Some(value) = self {
123            true.write(writer)?;
124            value.write_prefixed_bound::<P>(writer, bound)
125        } else {
126            false.write(writer)
127        }
128    }
129}