Skip to main content

object_rainbow/
none_terminated.rs

1use crate::*;
2
3#[derive(Debug, ParseAsInline, Clone, Copy, Default, Tagged)]
4pub struct Nt<T>(pub T);
5
6impl<T> PartialEq for Nt<T>
7where
8    for<'a> &'a T: IntoIterator<Item: PartialEq>,
9{
10    fn eq(&self, other: &Self) -> bool {
11        self.into_iter().eq(other)
12    }
13}
14
15impl<T> Eq for Nt<T> where for<'a> &'a T: IntoIterator<Item: Eq> {}
16
17impl<T> PartialOrd for Nt<T>
18where
19    for<'a> &'a T: IntoIterator<Item: PartialOrd>,
20{
21    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
22        self.into_iter().partial_cmp(other)
23    }
24}
25
26impl<T> Ord for Nt<T>
27where
28    for<'a> &'a T: IntoIterator<Item: Ord>,
29{
30    fn cmp(&self, other: &Self) -> Ordering {
31        self.into_iter().cmp(other)
32    }
33}
34
35impl<T: FromIterator<A>, A> FromIterator<A> for Nt<T> {
36    fn from_iter<I: IntoIterator<Item = A>>(iter: I) -> Self {
37        Self(iter.into_iter().collect())
38    }
39}
40
41impl<T: IntoIterator> IntoIterator for Nt<T> {
42    type Item = T::Item;
43
44    type IntoIter = T::IntoIter;
45
46    fn into_iter(self) -> Self::IntoIter {
47        self.0.into_iter()
48    }
49}
50
51impl<'a, T> IntoIterator for &'a Nt<T>
52where
53    &'a T: IntoIterator,
54{
55    type Item = <&'a T as IntoIterator>::Item;
56
57    type IntoIter = <&'a T as IntoIterator>::IntoIter;
58
59    fn into_iter(self) -> Self::IntoIter {
60        self.0.into_iter()
61    }
62}
63
64impl<'a, T> IntoIterator for &'a mut Nt<T>
65where
66    &'a mut T: IntoIterator,
67{
68    type Item = <&'a mut T as IntoIterator>::Item;
69
70    type IntoIter = <&'a mut T as IntoIterator>::IntoIter;
71
72    fn into_iter(self) -> Self::IntoIter {
73        self.0.into_iter()
74    }
75}
76
77impl<T> Deref for Nt<T> {
78    type Target = T;
79
80    fn deref(&self) -> &Self::Target {
81        &self.0
82    }
83}
84
85impl<T> DerefMut for Nt<T> {
86    fn deref_mut(&mut self) -> &mut Self::Target {
87        &mut self.0
88    }
89}
90
91impl<T> ToOutput for Nt<T>
92where
93    for<'a> &'a T: IntoIterator,
94    for<'a> Option<<&'a T as IntoIterator>::Item>: InlineOutput,
95{
96    fn to_output(&self, output: &mut impl Output) {
97        for item in self {
98            Some(item).to_output(output);
99        }
100        None.to_output(output);
101    }
102}
103
104impl<T> InlineOutput for Nt<T>
105where
106    for<'a> &'a T: IntoIterator,
107    for<'a> Option<<&'a T as IntoIterator>::Item>: InlineOutput,
108{
109}
110
111impl<T> ByteOrd for Nt<T>
112where
113    for<'a> &'a T: IntoIterator<Item: ByteOrd>,
114    for<'a> Option<<&'a T as IntoIterator>::Item>: ByteOrd + InlineOutput,
115{
116    fn bytes_cmp(&self, other: &Self) -> Ordering {
117        self.iter_bytes_cmp(other)
118    }
119}
120
121impl<T> ListHashes for Nt<T>
122where
123    for<'a> &'a T: IntoIterator<Item: ListHashes>,
124{
125    fn list_hashes(&self, f: &mut impl FnMut(Hash)) {
126        self.iter_list_hashes(f);
127    }
128}
129
130impl<T> Topological for Nt<T>
131where
132    for<'a> &'a T: IntoIterator<Item: Topological>,
133{
134    fn traverse(&self, visitor: &mut impl PointVisitor) {
135        self.iter_traverse(visitor);
136    }
137}
138
139impl<T: IntoIterator<Item = A> + FromIterator<A>, A, I: ParseInput> ParseInline<I> for Nt<T>
140where
141    Option<A>: ParseInline<I>,
142{
143    fn parse_inline(input: &mut I) -> crate::Result<Self> {
144        let mut items = Vec::new();
145        while let Some(item) = input.parse_inline()? {
146            items.push(item);
147        }
148        Ok(Self(items.into_iter().collect()))
149    }
150}
151
152#[derive(Debug, Clone, Copy, Default, ParseAsInline, Tagged)]
153pub struct NtString<T>(pub T);
154
155impl<T: AsRef<str>> PartialEq for NtString<T> {
156    fn eq(&self, other: &Self) -> bool {
157        self.as_ref() == other.as_ref()
158    }
159}
160
161impl<T: AsRef<str>> Eq for NtString<T> {}
162
163impl<T: AsRef<str>> PartialOrd for NtString<T> {
164    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
165        Some(self.cmp(other))
166    }
167}
168
169impl<T: AsRef<str>> Ord for NtString<T> {
170    fn cmp(&self, other: &Self) -> Ordering {
171        self.as_ref().cmp(other.as_ref())
172    }
173}
174
175impl<T> Deref for NtString<T> {
176    type Target = T;
177
178    fn deref(&self) -> &Self::Target {
179        &self.0
180    }
181}
182
183impl<T> DerefMut for NtString<T> {
184    fn deref_mut(&mut self) -> &mut Self::Target {
185        &mut self.0
186    }
187}
188
189impl<T: AsRef<str>> ToOutput for NtString<T> {
190    fn to_output(&self, output: &mut impl Output) {
191        self.as_ref().to_output(output);
192        None::<char>.to_output(output);
193    }
194}
195
196impl<T: AsRef<str>> InlineOutput for NtString<T> {}
197
198impl<T: AsRef<str>> ByteOrd for NtString<T> {
199    fn bytes_cmp(&self, other: &Self) -> Ordering {
200        self.as_ref().cmp(other.as_ref())
201    }
202}
203
204impl<T> ListHashes for NtString<T> {}
205impl<T> Topological for NtString<T> {}
206
207impl<T: FromIterator<char>, I: ParseInput> ParseInline<I> for NtString<T> {
208    fn parse_inline(input: &mut I) -> crate::Result<Self> {
209        Ok(Self(
210            input.parse_inline::<Nt<Vec<char>>>()?.into_iter().collect(),
211        ))
212    }
213}
214
215#[test]
216fn nt_string() -> crate::Result<()> {
217    let mut s = NtString("test".to_string());
218    assert_eq!(s.vec(), b"test\xFF");
219    s = s.reparse()?;
220    assert_eq!(s.as_str(), "test");
221    Ok(())
222}