object_rainbow/
zero_terminated.rs1use std::{fmt::Display, str::FromStr};
2
3use crate::{with_repr::WithRepr, *};
4
5#[derive(Debug, Tagged, ListHashes, Topological, ParseAsInline)]
9pub struct Zt<T> {
10 inner: Arc<WithRepr<T>>,
11}
12
13impl<T> PartialEq for Zt<T> {
14 fn eq(&self, other: &Self) -> bool {
15 self.inner == other.inner
16 }
17}
18
19impl<T> Eq for Zt<T> {}
20
21impl<T: ByteOrd> PartialOrd for Zt<T> {
22 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
23 Some(self.cmp(other))
24 }
25}
26
27impl<T: ByteOrd> Ord for Zt<T> {
28 fn cmp(&self, other: &Self) -> Ordering {
29 self.inner.cmp(&other.inner)
30 }
31}
32
33impl<T: ByteOrd> ByteOrd for Zt<T> {
34 fn bytes_cmp(&self, other: &Self) -> Ordering {
35 self.cmp(other)
36 }
37}
38
39impl<T: ToOutput> Zt<T> {
40 pub fn new(object: T) -> crate::Result<Self> {
44 let inner = WithRepr::new(object);
45 if inner.data().contains(&0) {
46 Err(Error::Zero)
47 } else {
48 Ok(Self {
49 inner: Arc::new(inner),
50 })
51 }
52 }
53}
54
55impl<T> Clone for Zt<T> {
56 fn clone(&self) -> Self {
57 Self {
58 inner: self.inner.clone(),
59 }
60 }
61}
62
63impl<T> Deref for Zt<T> {
64 type Target = T;
65
66 fn deref(&self) -> &Self::Target {
67 self.inner.object()
68 }
69}
70
71impl<T: ToOutput> ToOutput for Zt<T> {
72 fn to_output(&self, output: &mut impl Output) {
73 self.inner.to_output(output);
74 if output.is_real() {
75 output.write(&[0]);
76 }
77 }
78}
79
80impl<T: ToOutput> InlineOutput for Zt<T> {}
81
82impl<T: Parse<I>, I: ParseInput> ParseInline<I> for Zt<T> {
83 fn parse_inline(input: &mut I) -> crate::Result<Self> {
84 let inner = Arc::new(WithRepr::parse_zero_terminated(input)?);
85 Ok(Self { inner })
86 }
87}
88
89impl<T: MaybeHasNiche<MnArray = NoNiche<NicheForUnsized>>> MaybeHasNiche for Zt<T> {
90 type MnArray = NoNiche<NicheForUnsized>;
91}
92
93impl<T: FromStr<Err: 'static + Send + Sync + std::error::Error> + ToOutput> FromStr for Zt<T> {
94 type Err = Error;
95
96 fn from_str(s: &str) -> Result<Self> {
97 Self::new(s.parse().map_err(Error::parse)?)
98 }
99}
100
101impl<T: AsRef<str>> AsRef<str> for Zt<T> {
102 fn as_ref(&self) -> &str {
103 self.inner.object().as_ref()
104 }
105}
106
107impl<T: Display> Display for Zt<T> {
108 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109 self.inner.object().fmt(f)
110 }
111}