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