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