[go: up one dir, main page]

tora/
write.rs

1use std::io;
2use std::io::Write;
3
4macro_rules! serialize_io_num {
5    ($($t:ty),*) => {
6        $(
7        impl SerializeIo for $t {
8            fn serialize<W>(&self, w: &mut W) -> io::Result<()>
9            where W: Write
10            {
11                w.write_all(&self.to_le_bytes())
12            }
13        })*
14    }
15}
16
17/// An extension to the standard [Write] trait.
18pub trait ToraWrite {
19    /// Serialize and write the given data.
20    fn writes<S>(&mut self, s: &S) -> io::Result<()>
21    where
22        S: SerializeIo;
23}
24
25impl<W> ToraWrite for W
26where
27    W: Write,
28{
29    fn writes<S>(&mut self, s: &S) -> io::Result<()>
30    where
31        S: SerializeIo,
32    {
33        s.serialize(self)
34    }
35}
36
37/// A trait marking a type as capable of serializing itself to a writer.
38///
39/// ```
40/// use std::io;
41/// use std::io::Write;
42///
43/// pub trait SerializeIo {
44///     fn serialize<W>(&self, w: &mut W) -> io::Result<()>
45///     where
46///         W: Write;
47/// }
48///
49/// impl SerializeIo for i32 {
50///     fn serialize<W>(&self, w: &mut W) -> io::Result<()>
51///     where W: Write
52///     {
53///         w.write_all(&self.to_le_bytes())
54///     }
55/// }
56/// ```
57pub trait SerializeIo {
58    /// Serialize this type into the given writer.
59    ///
60    /// Implementations should call `write_all`.
61    fn serialize<W>(&self, w: &mut W) -> io::Result<()>
62    where
63        W: Write;
64}
65
66serialize_io_num!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64, usize);
67
68impl SerializeIo for char {
69    /// Serializes this char as a u32.
70    fn serialize<W>(&self, w: &mut W) -> io::Result<()>
71    where
72        W: Write,
73    {
74        (*self as u32).serialize(w)
75    }
76}
77
78impl SerializeIo for bool {
79    /// Serializes this bool as a u8.
80    fn serialize<W>(&self, w: &mut W) -> io::Result<()>
81    where
82        W: Write,
83    {
84        (*self as u8).serialize(w)
85    }
86}
87
88impl SerializeIo for () {
89    /// Immediately returns [Ok] of unit value.
90    fn serialize<W>(&self, _w: &mut W) -> io::Result<()>
91    where
92        W: Write,
93    {
94        Ok(())
95    }
96}
97
98impl<T, Z> SerializeIo for (T, Z)
99where
100    T: SerializeIo,
101    Z: SerializeIo,
102{
103    /// Writes a tuple of [T] and [Z], respectively.
104    fn serialize<W>(&self, w: &mut W) -> io::Result<()>
105    where
106        W: Write,
107    {
108        w.writes(&self.0)?;
109        w.writes(&self.1)
110    }
111}
112
113impl<T, Z, H> SerializeIo for (T, Z, H)
114where
115    T: SerializeIo,
116    Z: SerializeIo,
117    H: SerializeIo,
118{
119    /// Writes a tuple of [T], [Z], and [H], respectively.
120    fn serialize<W>(&self, w: &mut W) -> io::Result<()>
121    where
122        W: Write,
123    {
124        w.writes(&self.0)?;
125        w.writes(&self.1)?;
126        w.writes(&self.2)
127    }
128}
129
130impl SerializeIo for String {
131    fn serialize<W>(&self, w: &mut W) -> io::Result<()>
132    where
133        W: Write,
134    {
135        self.as_str().serialize(w)
136    }
137}
138
139impl<'a> SerializeIo for &'a str {
140    /// Write the given string in UTF-8.
141    ///
142    /// If the given string does not end in a NUL `0x00` byte, one will be appended.
143    fn serialize<W>(&self, w: &mut W) -> io::Result<()>
144    where
145        W: Write,
146    {
147        w.write_all(self.as_bytes())?;
148
149        if !self.ends_with(0u8 as char) {
150            w.write_all(&[0])?;
151        }
152        Ok(())
153    }
154}
155
156impl<T> SerializeIo for Option<T>
157where
158    T: SerializeIo,
159{
160    /// If this Option is Some, writes true and the inner value, else false.
161    fn serialize<W>(&self, w: &mut W) -> io::Result<()>
162    where
163        W: Write,
164    {
165        w.writes(&self.is_some())?;
166
167        if let Some(ref v) = self {
168            w.writes(v)?;
169        }
170        Ok(())
171    }
172}
173
174impl<T, E> SerializeIo for Result<T, E>
175where
176    T: SerializeIo,
177    E: SerializeIo,
178{
179    /// If this Result is an error, writes true and the inner error, else false and the inner value.
180    fn serialize<W>(&self, w: &mut W) -> io::Result<()>
181    where
182        W: Write,
183    {
184        w.writes(&self.is_err())?;
185
186        match self {
187            Ok(v) => w.writes(v),
188            Err(v) => w.writes(v),
189        }
190    }
191}
192
193impl<T, const N: usize> SerializeIo for [T; N]
194where
195    T: SerializeIo,
196{
197    fn serialize<W>(&self, w: &mut W) -> io::Result<()>
198    where
199        W: Write,
200    {
201        for t in self {
202            w.writes(t)?;
203        }
204        Ok(())
205    }
206}
207
208impl<T> SerializeIo for Box<T>
209where T: SerializeIo
210{
211    fn serialize<W>(&self, w: &mut W) -> io::Result<()>
212    where
213        W: Write,
214    {
215        w.writes(&**self)
216    }
217}
218
219macro_rules! dyn_impl {
220    ($t: ty) => {
221        #[cfg(feature = "dyn_impl")]
222        impl<T> SerializeIo for $t
223        where
224            T: SerializeIo,
225        {
226            fn serialize<W>(&self, w: &mut W) -> io::Result<()>
227            where
228                W: Write,
229            {
230                w.writes(&(self.len() as u32))?;
231
232                for obj in self.iter() {
233                    w.writes(obj)?;
234                }
235                Ok(())
236            }
237        }
238    };
239}
240
241dyn_impl!(&[T]);
242dyn_impl!(Vec<T>);