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 impl Output) {
53 if output.is_mangling() {
54 self.inner.object.to_output(output);
55 }
56 if output.is_real() {
57 self.inner.data.to_output(output);
58 output.write(&[0]);
59 }
60 }
61}
62
63impl<T: ToOutput> InlineOutput for Zt<T> {}
64
65impl<T: Parse<I>, I: ParseInput> ParseInline<I> for Zt<T> {
66 fn parse_inline(input: &mut I) -> crate::Result<Self> {
67 let data = input.parse_until_zero()?;
68 let object = input.reparse(data)?;
69 let data = data.into();
70 let inner = Arc::new(ZtInner { object, data });
71 Ok(Self { inner })
72 }
73}