object_rainbow/
zero_terminated.rs1use object_rainbow_derive::{ParseAsInline, Tagged, Topological};
2
3use crate::*;
4
5#[derive(Tagged, Topological)]
6struct ZtInner<T> {
7 object: T,
8 data: Vec<u8>,
9}
10
11#[derive(Tagged, 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: Parse<I>, I: ParseInput> ParseInline<I> for Zt<T> {
53 fn parse_inline(input: &mut I) -> crate::Result<Self> {
54 let data = input.parse_until_zero()?;
55 let object = input.reparse(data)?;
56 let data = data.into();
57 let inner = Arc::new(ZtInner { object, data });
58 Ok(Self { inner })
59 }
60}
61
62impl<T: Object<Extra>, Extra: 'static> Object<Extra> for Zt<T> {}
63impl<T: Object<Extra>, Extra: 'static> Inline<Extra> for Zt<T> {}
64impl<T: ReflessObject> ReflessObject for Zt<T> {}
65impl<T: ReflessObject> ReflessInline for Zt<T> {}