object_rainbow/
zero_terminated.rs

1use object_rainbow_derive::{ParseAsInline, Tagged, Topological};
2
3use crate::*;
4
5#[derive(Tagged, ListHashes, Topological)]
6struct ZtInner<T> {
7    object: T,
8    data: Vec<u8>,
9}
10
11#[derive(Tagged, ListHashes, Topological, ParseAsInline)]
12pub struct Zt<T> {
13    inner: Arc<ZtInner<T>>,
14}
15
16impl<T: ToOutput> Zt<T> {
17    pub fn new(object: T) -> crate::Result<Self> {
18        let data = object.vec();
19        if data.contains(&0) {
20            Err(Error::Zero)
21        } else {
22            Ok(Self {
23                inner: Arc::new(ZtInner { object, data }),
24            })
25        }
26    }
27}
28
29impl<T> Clone for Zt<T> {
30    fn clone(&self) -> Self {
31        Self {
32            inner: self.inner.clone(),
33        }
34    }
35}
36
37impl<T> Deref for Zt<T> {
38    type Target = T;
39
40    fn deref(&self) -> &Self::Target {
41        &self.inner.object
42    }
43}
44
45impl<T: ToOutput> ToOutput for Zt<T> {
46    fn to_output(&self, output: &mut dyn Output) {
47        self.inner.data.to_output(output);
48        output.write(&[0]);
49    }
50}
51
52impl<T: ToOutput> InlineOutput for Zt<T> {}
53
54impl<T: Parse<I>, I: ParseInput> ParseInline<I> for Zt<T> {
55    fn parse_inline(input: &mut I) -> crate::Result<Self> {
56        let data = input.parse_until_zero()?;
57        let object = input.reparse(data)?;
58        let data = data.into();
59        let inner = Arc::new(ZtInner { object, data });
60        Ok(Self { inner })
61    }
62}