object_rainbow/
length_prefixed.rs1use std::ops::{Add, Deref, DerefMut};
2
3use generic_array::ArrayLength;
4use typenum::{Sum, U8, Unsigned, tarr};
5
6use crate::{numeric::Le, *};
7
8#[derive(Topological, Tagged, Object, Inline, ReflessObject, ReflessInline, ParseAsInline)]
9pub struct Lp<T>(pub T);
10
11impl<T> Deref for Lp<T> {
12 type Target = T;
13
14 fn deref(&self) -> &Self::Target {
15 &self.0
16 }
17}
18
19impl<T> DerefMut for Lp<T> {
20 fn deref_mut(&mut self) -> &mut Self::Target {
21 &mut self.0
22 }
23}
24
25impl<T: ToOutput> ToOutput for Lp<T> {
26 fn to_output(&self, output: &mut dyn crate::Output) {
27 let data = self.0.vec();
28 let len = data.len();
29 let len = len as u64;
30 assert_ne!(len, u64::MAX);
31 let prefix = Le::<u64>(len);
32 prefix.to_output(output);
33 data.to_output(output);
34 }
35}
36
37impl<T: Size> Size for Lp<T>
38where
39 U8: Add<T::Size, Output: Unsigned>,
40{
41 type Size = Sum<U8, T::Size>;
42}
43
44impl<T: Size> MaybeHasNiche for Lp<T>
45where
46 U8: Add<T::Size, Output: ArrayLength>,
47{
48 type MnArray = tarr![SomeNiche<OneNiche<U8>>, NoNiche<ZeroNoNiche<T::Size>>];
49}
50
51impl<T: Parse<I>, I: ParseInput> ParseInline<I> for Lp<T> {
52 fn parse_inline(input: &mut I) -> crate::Result<Self> {
53 let prefix: Le<u64> = input.parse_inline()?;
54 let len = prefix.0;
55 let len = len.try_into().map_err(|_| Error::UnsupportedLength)?;
56 Ok(Self(input.parse_ahead(len)?))
57 }
58}
59
60#[test]
61fn prefixed() {
62 let a = Lp(vec![0, 1, 2]);
63 let data = a.vec();
64 let b = Lp::<Vec<u8>>::parse_slice_refless(&data).unwrap();
65 assert_eq!(*a, *b);
66}
67
68#[derive(Debug, Clone, ParseAsInline, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
69pub struct LpBytes(pub Vec<u8>);
70
71impl Deref for LpBytes {
72 type Target = Vec<u8>;
73
74 fn deref(&self) -> &Self::Target {
75 &self.0
76 }
77}
78
79impl DerefMut for LpBytes {
80 fn deref_mut(&mut self) -> &mut Self::Target {
81 &mut self.0
82 }
83}
84
85impl ToOutput for LpBytes {
86 fn to_output(&self, output: &mut dyn crate::Output) {
87 let data = &self.0;
88 let len = data.len();
89 let len = len as u64;
90 assert_ne!(len, u64::MAX);
91 let prefix = Le::<u64>(len);
92 prefix.to_output(output);
93 data.to_output(output);
94 }
95}
96
97impl<I: ParseInput> ParseInline<I> for LpBytes {
98 fn parse_inline(input: &mut I) -> crate::Result<Self> {
99 let prefix: Le<u64> = input.parse_inline()?;
100 let len = prefix.0;
101 let len = len.try_into().map_err(|_| Error::UnsupportedLength)?;
102 Ok(Self(input.parse_n(len)?.into()))
103 }
104}
105
106impl Tagged for LpBytes {}
107impl<E: 'static> Topological<E> for LpBytes {}
108impl<E: 'static> Object<E> for LpBytes {}
109impl<E: 'static> Inline<E> for LpBytes {}
110impl ReflessObject for LpBytes {}
111impl ReflessInline for LpBytes {}
112
113#[derive(Debug, Clone, ParseAsInline, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
114pub struct LpString(pub String);
115
116impl Deref for LpString {
117 type Target = String;
118
119 fn deref(&self) -> &Self::Target {
120 &self.0
121 }
122}
123
124impl DerefMut for LpString {
125 fn deref_mut(&mut self) -> &mut Self::Target {
126 &mut self.0
127 }
128}
129
130impl ToOutput for LpString {
131 fn to_output(&self, output: &mut dyn crate::Output) {
132 let data = self.0.as_bytes();
133 let len = data.len();
134 let len = len as u64;
135 assert_ne!(len, u64::MAX);
136 let prefix = Le::<u64>(len);
137 prefix.to_output(output);
138 data.to_output(output);
139 }
140}
141
142impl<I: ParseInput> ParseInline<I> for LpString {
143 fn parse_inline(input: &mut I) -> crate::Result<Self> {
144 String::from_utf8(input.parse_inline::<LpBytes>()?.0)
145 .map_err(Error::Utf8)
146 .map(Self)
147 }
148}
149
150impl Tagged for LpString {}
151impl<E: 'static> Topological<E> for LpString {}
152impl<E: 'static> Object<E> for LpString {}
153impl<E: 'static> Inline<E> for LpString {}
154impl ReflessObject for LpString {}
155impl ReflessInline for LpString {}