object_rainbow/
zero_terminated.rs1use 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)]
15pub struct Zt<T> {
16 inner: Arc<ZtInner<T>>,
17}
18
19impl<T: ToOutput> Zt<T> {
20 pub fn new(object: T) -> crate::Result<Self> {
24 let data = object.vec();
25 if data.contains(&0) {
26 Err(Error::Zero)
27 } else {
28 Ok(Self {
29 inner: Arc::new(ZtInner { object, data }),
30 })
31 }
32 }
33}
34
35impl<T> Clone for Zt<T> {
36 fn clone(&self) -> Self {
37 Self {
38 inner: self.inner.clone(),
39 }
40 }
41}
42
43impl<T> Deref for Zt<T> {
44 type Target = T;
45
46 fn deref(&self) -> &Self::Target {
47 &self.inner.object
48 }
49}
50
51impl<T: ToOutput> ToOutput for Zt<T> {
52 fn to_output(&self, output: &mut dyn Output) {
53 self.inner.data.to_output(output);
54 output.write(&[0]);
55 }
56}
57
58impl<T: ToOutput> InlineOutput for Zt<T> {}
59
60impl<T: Parse<I>, I: ParseInput> ParseInline<I> for Zt<T> {
61 fn parse_inline(input: &mut I) -> crate::Result<Self> {
62 let data = input.parse_until_zero()?;
63 let object = input.reparse(data)?;
64 let data = data.into();
65 let inner = Arc::new(ZtInner { object, data });
66 Ok(Self { inner })
67 }
68}