Skip to main content

harmos_domain/message/
postcard.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10/* === Modules === */
11
12/* === Re-Exports === */
13
14/* === Imports === */
15
16// Standard Library Imports
17
18// Third Party Imports
19
20// Local Imports
21use super::{MessageError, decoding_add, decoding_multiply, decoding_vector};
22
23/* === Constants === */
24
25const MAX_DEPTH: usize = 32;
26const MAX_VALUES: usize = 1_048_576;
27
28/* === Macros === */
29
30/* === Type Aliases === */
31
32/* === Structs === */
33
34struct Append<'a>(&'a mut Vec<u8>);
35
36#[derive(Clone)]
37pub struct Reader<'a> {
38    bytes: &'a [u8],
39    depth: usize,
40    remaining: usize,
41}
42
43/* === Enums === */
44
45/* === Traits === */
46
47pub trait Value: Sized + Send + Sync {
48    fn write(&self, bytes: &mut Vec<u8>);
49    fn size(&self) -> usize;
50    fn memory(input: &mut Reader<'_>) -> Result<usize, MessageError>;
51    fn read(input: &mut Reader<'_>) -> Result<Self, MessageError>;
52
53    fn size_many(values: &[Self]) -> usize {
54        values.iter().fold(0usize, |size, value| size.saturating_add(value.size()))
55    }
56    fn write_many(values: &[Self], bytes: &mut Vec<u8>) {
57        for value in values {
58            value.write(bytes);
59        }
60    }
61    fn memory_many(input: &mut Reader<'_>, count: usize) -> Result<usize, MessageError> {
62        input.claim(count)?;
63        let mut bytes = decoding_multiply(count, std::mem::size_of::<Self>())?;
64        for _ in 0..count {
65            bytes = decoding_add(bytes, Self::memory(input)?.saturating_sub(std::mem::size_of::<Self>()))?;
66        }
67        Ok(bytes)
68    }
69    fn read_many(input: &mut Reader<'_>, count: usize) -> Result<Vec<Self>, MessageError> {
70        input.claim(count)?;
71        let mut values = decoding_vector(count)?;
72        for _ in 0..count {
73            values.push(Self::read(input)?);
74        }
75        Ok(values)
76    }
77}
78
79/* === Implementations === */
80
81impl Extend<u8> for Append<'_> {
82    fn extend<I: IntoIterator<Item = u8>>(&mut self, iter: I) {
83        self.0.extend(iter);
84    }
85}
86impl<'a> Reader<'a> {
87    pub fn new(bytes: &'a [u8]) -> Self {
88        Self { bytes, depth: 0, remaining: MAX_VALUES }
89    }
90    pub fn remaining(&self) -> &'a [u8] {
91        self.bytes
92    }
93    pub fn finish(self) -> Result<(), MessageError> {
94        if self.bytes.is_empty() { Ok(()) } else { Err(MessageError::borrowed("trailing Postcard bytes")) }
95    }
96    pub fn value<T: serde::Deserialize<'a>>(&mut self) -> Result<T, MessageError> {
97        self.claim(1)?;
98        let (value, rest) = ::postcard::take_from_bytes(self.bytes).map_err(|_| MessageError::borrowed("invalid Postcard value"))?;
99        self.bytes = rest;
100        Ok(value)
101    }
102    pub fn take(&mut self, count: usize) -> Result<&'a [u8], MessageError> {
103        let (value, rest) = self.bytes.split_at_checked(count).ok_or_else(|| MessageError::borrowed("truncated Postcard bytes"))?;
104        self.bytes = rest;
105        Ok(value)
106    }
107    pub fn claim(&mut self, count: usize) -> Result<(), MessageError> {
108        self.remaining =
109            self.remaining.checked_sub(count).ok_or_else(|| MessageError::borrowed("Postcard structural work limit exceeded"))?;
110        Ok(())
111    }
112    pub fn nested<T>(&mut self, read: impl FnOnce(&mut Self) -> Result<T, MessageError>) -> Result<T, MessageError> {
113        if self.depth >= MAX_DEPTH {
114            return Err(MessageError::borrowed("Postcard nesting limit exceeded"));
115        }
116        self.claim(1)?;
117        self.depth += 1;
118        let result = read(self);
119        self.depth -= 1;
120        result
121    }
122}
123
124macro_rules! scalar {
125    ($($ty:ty),* $(,)?) => {$(
126        impl Value for $ty {
127            fn write(&self, bytes: &mut Vec<u8>) {
128                ::postcard::to_extend(self, Append(bytes)).expect("scalar Postcard encoding is infallible");
129            }
130            fn size(&self) -> usize {
131                ::postcard::experimental::serialized_size(self).expect("scalar Postcard sizing is infallible")
132            }
133            fn memory(input: &mut Reader<'_>) -> Result<usize, MessageError> {
134                let _: Self = input.value()?;
135                Ok(std::mem::size_of::<Self>())
136            }
137            fn read(input: &mut Reader<'_>) -> Result<Self, MessageError> { input.value() }
138        }
139    )*};
140}
141scalar!((), bool, u32, u64, i32, i64, f32, f64, usize);
142
143impl Value for u8 {
144    fn write(&self, bytes: &mut Vec<u8>) {
145        bytes.push(*self);
146    }
147    fn size(&self) -> usize {
148        1
149    }
150    fn memory(input: &mut Reader<'_>) -> Result<usize, MessageError> {
151        input.take(1)?;
152        Ok(1)
153    }
154    fn read(input: &mut Reader<'_>) -> Result<Self, MessageError> {
155        Ok(input.take(1)?[0])
156    }
157    fn size_many(values: &[Self]) -> usize {
158        values.len()
159    }
160    fn write_many(values: &[Self], bytes: &mut Vec<u8>) {
161        bytes.extend_from_slice(values);
162    }
163    fn memory_many(input: &mut Reader<'_>, count: usize) -> Result<usize, MessageError> {
164        input.take(count)?;
165        Ok(count)
166    }
167    fn read_many(input: &mut Reader<'_>, count: usize) -> Result<Vec<Self>, MessageError> {
168        Ok(Box::<[u8]>::from(input.take(count)?).into_vec())
169    }
170}
171
172macro_rules! nonzero {
173    ($($ty:ty => $scalar:ty),* $(,)?) => {$(
174        impl Value for $ty {
175            fn write(&self, bytes: &mut Vec<u8>) { self.get().write(bytes); }
176            fn size(&self) -> usize { self.get().size() }
177            fn memory(input: &mut Reader<'_>) -> Result<usize, MessageError> {
178                Self::read(input)?;
179                Ok(std::mem::size_of::<Self>())
180            }
181            fn read(input: &mut Reader<'_>) -> Result<Self, MessageError> {
182                Self::new(<$scalar as Value>::read(input)?)
183                    .ok_or_else(|| MessageError::borrowed("zero is not a nonzero value"))
184            }
185        }
186    )*};
187}
188nonzero!(std::num::NonZeroU32 => u32, std::num::NonZeroU64 => u64);
189
190// Fixed Byte Values Keep The Length-Prefixed Bytes Shape And Reject Wrong Widths.
191impl<const N: usize> Value for [u8; N] {
192    fn write(&self, bytes: &mut Vec<u8>) {
193        (N as u64).write(bytes);
194        bytes.extend_from_slice(self);
195    }
196
197    fn size(&self) -> usize {
198        (N as u64).size().saturating_add(N)
199    }
200
201    fn memory(input: &mut Reader<'_>) -> Result<usize, MessageError> {
202        Self::read(input)?;
203        Ok(std::mem::size_of::<Self>())
204    }
205
206    fn read(input: &mut Reader<'_>) -> Result<Self, MessageError> {
207        if input.value::<usize>()? != N {
208            return Err(MessageError::borrowed("fixed byte value has the wrong length"));
209        }
210        Ok(input.take(N)?.try_into().expect("checked fixed byte size"))
211    }
212}
213
214impl Value for String {
215    fn write(&self, bytes: &mut Vec<u8>) {
216        ::postcard::to_extend(self, Append(bytes)).expect("string Postcard encoding is infallible");
217    }
218    fn size(&self) -> usize {
219        self.len().saturating_add(self.len().size())
220    }
221    fn memory(input: &mut Reader<'_>) -> Result<usize, MessageError> {
222        let text: &str = input.value()?;
223        decoding_add(std::mem::size_of::<Self>(), text.len())
224    }
225    fn read(input: &mut Reader<'_>) -> Result<Self, MessageError> {
226        let text: &str = input.value()?;
227        Ok(Box::<str>::from(text).into_string())
228    }
229}
230impl<T: Value> Value for Vec<T> {
231    fn write(&self, bytes: &mut Vec<u8>) {
232        self.len().write(bytes);
233        T::write_many(self, bytes);
234    }
235    fn size(&self) -> usize {
236        self.len().size().saturating_add(T::size_many(self))
237    }
238    fn memory(input: &mut Reader<'_>) -> Result<usize, MessageError> {
239        input.nested(|input| {
240            let count: usize = input.value()?;
241            decoding_add(std::mem::size_of::<Self>(), T::memory_many(input, count)?)
242        })
243    }
244    fn read(input: &mut Reader<'_>) -> Result<Self, MessageError> {
245        input.nested(|input| {
246            let count = input.value()?;
247            T::read_many(input, count)
248        })
249    }
250}
251// A Box Shares Its Pointee's Bytes, Nesting And Work Limits; Only Ownership Differs
252impl<T: Value> Value for Box<T> {
253    fn write(&self, bytes: &mut Vec<u8>) {
254        (**self).write(bytes);
255    }
256    fn size(&self) -> usize {
257        (**self).size()
258    }
259    fn memory(input: &mut Reader<'_>) -> Result<usize, MessageError> {
260        decoding_add(std::mem::size_of::<Self>(), T::memory(input)?)
261    }
262    fn read(input: &mut Reader<'_>) -> Result<Self, MessageError> {
263        T::read(input).map(Box::new)
264    }
265}
266impl<T: Value> Value for Option<T> {
267    fn write(&self, bytes: &mut Vec<u8>) {
268        self.is_some().write(bytes);
269        if let Some(value) = self {
270            value.write(bytes);
271        }
272    }
273    fn size(&self) -> usize {
274        1usize.saturating_add(self.as_ref().map_or(0, Value::size))
275    }
276    fn memory(input: &mut Reader<'_>) -> Result<usize, MessageError> {
277        input.nested(|input| {
278            let present: bool = input.value()?;
279            let allocation = if present { T::memory(input)?.saturating_sub(std::mem::size_of::<T>()) } else { 0 };
280            decoding_add(std::mem::size_of::<Self>(), allocation)
281        })
282    }
283    fn read(input: &mut Reader<'_>) -> Result<Self, MessageError> {
284        input.nested(|input| if input.value::<bool>()? { T::read(input).map(Some) } else { Ok(None) })
285    }
286}
287
288/* === Public Functions === */
289
290/* === Private Functions === */
291
292/* === Tests === */
293
294#[cfg(test)]
295mod tests {
296    use super::*;
297
298    #[test]
299    fn fixed_bytes_format() {
300        let digest = [7_u8; 32];
301        let mut bytes = Vec::new();
302        digest.write(&mut bytes);
303        assert_eq!(bytes[0], 32);
304        assert_eq!(&bytes[1..], &digest);
305        assert_eq!(digest.size(), 33);
306        let mut input = Reader::new(&bytes);
307        assert_eq!(<[u8; 32]>::read(&mut input).unwrap(), digest);
308        input.finish().unwrap();
309        assert_eq!(<[u8; 32]>::memory(&mut Reader::new(&bytes)).unwrap(), 32);
310        bytes[0] = 31;
311        assert!(<[u8; 32]>::read(&mut Reader::new(&bytes)).is_err());
312        bytes[0] = 32;
313        bytes.pop();
314        assert!(<[u8; 32]>::read(&mut Reader::new(&bytes)).is_err());
315    }
316}