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)]
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}