1use crate::{CborLen, Encode, Encoder, primitive};
4#[cfg(feature = "alloc")]
5use crate::{Decode, Decoder};
6
7pub mod fixed;
8pub mod map;
9
10#[derive(#[automatically_derived]
impl<E: ::core::fmt::Debug> ::core::fmt::Debug for Error<E> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Error::Malformed(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Malformed", &__self_0),
Error::Element(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Element", &__self_0),
}
}
}Debug, #[automatically_derived]
impl<E: ::core::clone::Clone> ::core::clone::Clone for Error<E> {
#[inline]
fn clone(&self) -> Error<E> {
match self {
Error::Malformed(__self_0) =>
Error::Malformed(::core::clone::Clone::clone(__self_0)),
Error::Element(__self_0) =>
Error::Element(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]
impl<E: ::core::marker::Copy> ::core::marker::Copy for Error<E> { }Copy, #[automatically_derived]
impl<E: ::core::cmp::PartialEq> ::core::cmp::PartialEq for Error<E> {
#[inline]
fn eq(&self, other: &Error<E>) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(Error::Malformed(__self_0), Error::Malformed(__arg1_0)) =>
__self_0 == __arg1_0,
(Error::Element(__self_0), Error::Element(__arg1_0)) =>
__self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq, #[automatically_derived]
impl<E: ::core::cmp::Eq> ::core::cmp::Eq for Error<E> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<primitive::Error>;
let _: ::core::cmp::AssertParamIsEq<E>;
}
}Eq, #[automatically_derived]
impl<E: ::core::hash::Hash> ::core::hash::Hash for Error<E> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
Error::Malformed(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
Error::Element(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
}
}
}Hash)]
12pub enum Error<E> {
13 Malformed(primitive::Error),
15 Element(E),
17}
18
19impl<E> Error<E> {
20 pub fn map<O>(self, f: impl FnOnce(E) -> O) -> Error<O> {
22 match self {
23 Error::Malformed(e) => Error::Malformed(e),
24 Error::Element(e) => Error::Element(f(e)),
25 }
26 }
27}
28
29impl<E: core::fmt::Display> core::fmt::Display for Error<E> {
30 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
31 match self {
32 Error::Malformed(e) => f.write_fmt(format_args!("{0}", e))write!(f, "{e}"),
33 Error::Element(e) => f.write_fmt(format_args!("container element: {0}", e))write!(f, "container element: {e}"),
34 }
35 }
36}
37
38impl<E> From<primitive::Error> for Error<E> {
39 fn from(e: primitive::Error) -> Self {
40 Error::Malformed(e)
41 }
42}
43
44impl<E> From<crate::EndOfInput> for Error<E> {
45 fn from(e: crate::EndOfInput) -> Self {
46 Error::Malformed(primitive::Error::EndOfInput(e))
47 }
48}
49
50impl<E: core::error::Error + 'static> core::error::Error for Error<E> {
51 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
52 match self {
53 Error::Malformed(e) => Some(e),
54 Error::Element(e) => Some(e),
55 }
56 }
57}
58
59#[cfg(feature = "alloc")]
60impl<'b, T> Decode<'b> for alloc::collections::BinaryHeap<T>
61where
62 T: Decode<'b> + Ord,
63{
64 type Error = Error<T::Error>;
65
66 fn decode(d: &mut Decoder<'b>) -> Result<Self, Self::Error> {
67 let mut visitor = d.array_visitor()?;
68 let mut v = Self::new();
69 while let Some(elem) = visitor.visit() {
70 v.push(elem.map_err(Error::Element)?);
71 }
72
73 Ok(v)
74 }
75}
76
77#[cfg(feature = "std")]
78impl<'b, T, S> Decode<'b> for std::collections::HashSet<T, S>
79where
80 T: Decode<'b> + Eq + std::hash::Hash,
81 S: std::hash::BuildHasher + std::default::Default,
82{
83 type Error = Error<T::Error>;
84
85 fn decode(d: &mut Decoder<'b>) -> Result<Self, Self::Error> {
86 let mut visitor = d.array_visitor()?;
87 let mut v = Self::default();
88 while let Some(elem) = visitor.visit() {
89 v.insert(elem.map_err(Error::Element)?);
90 }
91
92 Ok(v)
93 }
94}
95
96#[cfg(feature = "alloc")]
97impl<'b, T> Decode<'b> for alloc::collections::BTreeSet<T>
98where
99 T: Decode<'b> + Ord,
100{
101 type Error = Error<T::Error>;
102
103 fn decode(d: &mut Decoder<'b>) -> Result<Self, Self::Error> {
104 let mut visitor = d.array_visitor()?;
105 let mut v = Self::new();
106 while let Some(elem) = visitor.visit() {
107 v.insert(elem.map_err(Error::Element)?);
108 }
109 Ok(v)
110 }
111}
112
113#[cfg(feature = "alloc")]
114macro_rules! decode_sequential {
115 ($($t:ty, $push:ident)*) => {
116 $(
117 impl<'b, T: Decode<'b>> Decode<'b> for $t {
118 type Error = Error<T::Error>;
119
120 fn decode(d: &mut Decoder<'b>) -> Result<Self, Self::Error> {
121 let mut visitor = d.array_visitor()?;
122 let mut v = Self::new();
123 while let Some(x) = visitor.visit() {
124 v.$push(x.map_err(Error::Element)?)
125 }
126 Ok(v)
127 }
128 }
129 )*
130 }
131}
132
133#[cfg(feature = "alloc")]
134impl<'b, T: Decode<'b>> Decode<'b> for alloc::collections::LinkedList<T> {
type Error = Error<T::Error>;
fn decode(d: &mut Decoder<'b>) -> Result<Self, Self::Error> {
let mut visitor = d.array_visitor()?;
let mut v = Self::new();
while let Some(x) = visitor.visit() {
v.push_back(x.map_err(Error::Element)?)
}
Ok(v)
}
}decode_sequential! {
135 alloc::vec::Vec<T>, push
136 alloc::collections::VecDeque<T>, push_back
137 alloc::collections::LinkedList<T>, push_back
138}
139
140macro_rules! encode_sequential {
141 ($($t:ty)*) => {
142 $(
143 impl<T: Encode> Encode for $t {
144 fn encode<W: embedded_io::Write>(&self, e: &mut Encoder<W>) -> Result<(), W::Error> {
145 e.array(self.len())?;
146 for x in self {
147 x.encode(e)?
148 }
149 Ok(())
150 }
151 }
152
153 impl<T: CborLen> CborLen for $t {
154 fn cbor_len(&self) -> usize {
155 let n = self.len();
156 n.cbor_len() + self.iter().map(|x| x.cbor_len()).sum::<usize>()
157 }
158 }
159 )*
160 }
161}
162
163#[cfg(feature = "alloc")]
164impl<T: Encode> Encode for alloc::collections::BTreeSet<T> {
fn encode<W: embedded_io::Write>(&self, e: &mut Encoder<W>)
-> Result<(), W::Error> {
e.array(self.len())?;
for x in self { x.encode(e)? }
Ok(())
}
}
impl<T: CborLen> CborLen for alloc::collections::BTreeSet<T> {
fn cbor_len(&self) -> usize {
let n = self.len();
n.cbor_len() + self.iter().map(|x| x.cbor_len()).sum::<usize>()
}
}encode_sequential! {
165 alloc::vec::Vec<T>
166 alloc::collections::VecDeque<T>
167 alloc::collections::LinkedList<T>
168 alloc::collections::BinaryHeap<T>
169 alloc::collections::BTreeSet<T>
170}
171
172#[cfg(feature = "std")]
173impl<T: Encode> Encode for std::collections::HashSet<T> {
fn encode<W: embedded_io::Write>(&self, e: &mut Encoder<W>)
-> Result<(), W::Error> {
e.array(self.len())?;
for x in self { x.encode(e)? }
Ok(())
}
}
impl<T: CborLen> CborLen for std::collections::HashSet<T> {
fn cbor_len(&self) -> usize {
let n = self.len();
n.cbor_len() + self.iter().map(|x| x.cbor_len()).sum::<usize>()
}
}encode_sequential! {
174 std::collections::HashSet<T>
175}
176
177impl<T: Encode> Encode for [T] {
fn encode<W: embedded_io::Write>(&self, e: &mut Encoder<W>)
-> Result<(), W::Error> {
e.array(self.len())?;
for x in self { x.encode(e)? }
Ok(())
}
}
impl<T: CborLen> CborLen for [T] {
fn cbor_len(&self) -> usize {
let n = self.len();
n.cbor_len() + self.iter().map(|x| x.cbor_len()).sum::<usize>()
}
}encode_sequential!([T]);
178
179#[cfg(all(test, feature = "alloc"))]
180mod tests {
181 use crate::{CborLen, Decode, Decoder, Encode, Encoder, test};
182
183 const EMPTY_ARRAY: &[u8] = &[0x80];
184 const EMPTY_INDEF: &[u8] = &[0x9f, 0xff];
185
186 #[cfg(feature = "alloc")]
187 fn test_binary_heap<'a, T>(cbor: &'a [u8], expected: &[T])
188 where
189 T: Decode<'a> + Encode + CborLen + Ord + PartialEq + core::fmt::Debug,
190 {
191 use alloc::collections::BinaryHeap;
192
193 let heap = BinaryHeap::<T>::decode(&mut Decoder(cbor)).unwrap();
194 let mut buf = Vec::new();
195 heap.encode(&mut Encoder(&mut buf)).unwrap();
196 assert_eq!(heap.cbor_len(), buf.len());
197 assert_eq!(heap.into_sorted_vec(), expected);
198 }
199
200 #[test]
201 fn definite() {
202 #[cfg(feature = "alloc")]
203 {
204 use alloc::{collections::*, string::String, vec::Vec};
205
206 assert!(test::<Vec<&str>>(Vec::new(), EMPTY_ARRAY).unwrap());
207 assert!(
208 test(
209 vec!["a", "b", "c"],
210 &[0x83, 0x61, 0x61, 0x61, 0x62, 0x61, 0x63]
211 )
212 .unwrap()
213 );
214
215 assert!(test::<VecDeque<String>>(VecDeque::new(), EMPTY_ARRAY).unwrap());
216 assert!(
217 test(
218 VecDeque::from([String::from("hi"), String::from("yo")]),
219 &[0x82, 0x62, 0x68, 0x69, 0x62, 0x79, 0x6f]
220 )
221 .unwrap()
222 );
223
224 assert!(test::<LinkedList<Option<i32>>>(LinkedList::new(), EMPTY_ARRAY).unwrap());
225 assert!(
226 test(
227 LinkedList::from([Some(-5), None, Some(10)]),
228 &[0x83, 0x24, 0xf6, 0x0a]
229 )
230 .unwrap()
231 );
232
233 test_binary_heap::<usize>(EMPTY_ARRAY, &[]);
234 test_binary_heap::<usize>(
235 &[0x83, 0x18, 0x64, 0x18, 0xc8, 0x18, 0x96],
236 &[100, 150, 200],
237 );
238
239 assert!(test::<BTreeSet<i32>>(BTreeSet::new(), EMPTY_ARRAY).unwrap());
240 assert!(
241 test(
242 BTreeSet::from([-10, 0, 10, 20]),
243 &[0x84, 0x29, 0x00, 0x0a, 0x14]
244 )
245 .unwrap()
246 );
247 }
248
249 #[cfg(feature = "std")]
250 {
251 use std::collections::HashSet;
252 assert!(test::<HashSet<&str>>(HashSet::new(), EMPTY_ARRAY).unwrap());
253 test(
254 HashSet::from(["foo", "bar"]),
255 &[0x82, 0x63, 0x66, 0x6f, 0x6f, 0x63, 0x62, 0x61, 0x72],
256 )
257 .unwrap();
258 }
259 }
260
261 #[cfg(feature = "alloc")]
262 #[test]
263 fn indefinite() {
264 use alloc::{collections::*, string::String, vec::Vec};
265
266 assert!(!test::<Vec<&str>>(Vec::new(), EMPTY_INDEF).unwrap());
267 assert!(!test(vec!["x", "y"], &[0x9f, 0x61, 0x78, 0x61, 0x79, 0xff]).unwrap());
268
269 assert!(!test::<VecDeque<String>>(VecDeque::new(), EMPTY_INDEF).unwrap());
270 assert!(
271 !test(
272 VecDeque::from([String::from("a")]),
273 &[0x9f, 0x61, 0x61, 0xff]
274 )
275 .unwrap()
276 );
277
278 assert!(!test::<LinkedList<Option<i32>>>(LinkedList::new(), EMPTY_INDEF).unwrap());
279 assert!(!test(LinkedList::from([Some(1), None]), &[0x9f, 0x01, 0xf6, 0xff]).unwrap());
280
281 test_binary_heap::<usize>(EMPTY_INDEF, &[]);
282 test_binary_heap::<usize>(&[0x9f, 0x18, 0x32, 0x18, 0x64, 0xff], &[50, 100]);
283
284 assert!(!test::<BTreeSet<i32>>(BTreeSet::new(), EMPTY_INDEF).unwrap());
285 assert!(!test(BTreeSet::from([5, 10]), &[0x9f, 0x05, 0x0a, 0xff]).unwrap());
286
287 #[cfg(feature = "std")]
288 {
289 use std::collections::HashSet;
290 assert!(!test::<HashSet<&str>>(HashSet::new(), EMPTY_INDEF).unwrap());
291 assert!(
292 !test(
293 HashSet::from(["test"]),
294 &[0x9f, 0x64, 0x74, 0x65, 0x73, 0x74, 0xff]
295 )
296 .unwrap()
297 );
298 }
299 }
300
301 #[cfg(feature = "alloc")]
302 #[test]
303 fn nested() {
304 use alloc::{string::String, vec};
305 assert!(
306 test(
307 vec![
308 vec![String::from("a")],
309 vec![String::from("b"), String::from("c")]
310 ],
311 &[0x82, 0x81, 0x61, 0x61, 0x82, 0x61, 0x62, 0x61, 0x63]
312 )
313 .unwrap()
314 );
315 }
316
317 #[cfg(feature = "alloc")]
318 #[test]
319 fn long() {
320 use alloc::vec::Vec;
321 let mut cbor = vec![0x98, 25];
322 for i in 0..25 {
323 cbor.push(0x18);
324 cbor.push(i);
325 }
326 assert!(!test((0..25).map(|i| i as usize).collect::<Vec<usize>>(), &cbor).unwrap());
327 }
328}