1use crate::{
2 Format,
3 decode::{
4 ArrayDecoder, Decode, DecodeBorrowed, Error, MapDecoder, ReferenceDecoder, ReferenceStr,
5 ReferenceStrDecoder,
6 },
7 io::IoRead,
8};
9
10#[derive(Debug, Clone, Copy, PartialEq)]
15pub enum Any<'de> {
16 Nil,
18 Bool(bool),
20 U8(u8),
22 U16(u16),
24 U32(u32),
26 U64(u64),
28 I8(i8),
30 I16(i16),
32 I32(i32),
34 I64(i64),
36 F32(f32),
38 F64(f64),
40 StrBorrowed(&'de str),
42 StrCopied(usize),
44 BinBorrowed(&'de [u8]),
46 BinCopied(usize),
48 Array(usize),
50 Map(usize),
52 ExtBorrowed {
54 r#type: i8,
56 data: &'de [u8],
58 },
59 ExtCopied {
61 r#type: i8,
63 len: usize,
65 },
66}
67
68impl<'de> DecodeBorrowed<'de> for Any<'de> {
69 type Value = Self;
70 fn decode_borrowed_with_format<R>(
71 format: Format,
72 reader: &mut R,
73 ) -> Result<<Self as DecodeBorrowed<'de>>::Value, Error<R::Error>>
74 where
75 R: IoRead<'de>,
76 {
77 match format {
78 Format::Nil => Ok(Any::Nil),
79 Format::False | Format::True => bool::decode_with_format(format, reader).map(Any::Bool),
80
81 Format::PositiveFixInt(_) | Format::Uint8 => {
82 u8::decode_with_format(format, reader).map(Any::U8)
83 }
84 Format::Uint16 => u16::decode_with_format(format, reader).map(Any::U16),
85 Format::Uint32 => u32::decode_with_format(format, reader).map(Any::U32),
86 Format::Uint64 => u64::decode_with_format(format, reader).map(Any::U64),
87 Format::NegativeFixInt(_) | Format::Int8 => {
88 i8::decode_with_format(format, reader).map(Any::I8)
89 }
90 Format::Int16 => i16::decode_with_format(format, reader).map(Any::I16),
91 Format::Int32 => i32::decode_with_format(format, reader).map(Any::I32),
92 Format::Int64 => i64::decode_with_format(format, reader).map(Any::I64),
93
94 Format::Float32 => f32::decode_with_format(format, reader).map(Any::F32),
95 Format::Float64 => f64::decode_with_format(format, reader).map(Any::F64),
96
97 Format::FixStr(_) | Format::Str8 | Format::Str16 | Format::Str32 => {
98 ReferenceStrDecoder::decode_with_format(format, reader).map(|s| match s {
99 ReferenceStr::Borrowed(s) => Any::StrBorrowed(s),
100 ReferenceStr::Copied(s) => Any::StrCopied(s.len()),
101 })
102 }
103
104 Format::Bin8 | Format::Bin16 | Format::Bin32 => {
105 ReferenceDecoder::decode_with_format(format, reader).map(|b| match b {
106 crate::io::Reference::Borrowed(items) => Any::BinBorrowed(items),
107 crate::io::Reference::Copied(items) => Any::BinCopied(items.len()),
108 })
109 }
110
111 Format::FixExt1
112 | Format::FixExt2
113 | Format::FixExt4
114 | Format::FixExt8
115 | Format::FixExt16
116 | Format::Ext8
117 | Format::Ext16
118 | Format::Ext32 => {
119 let (length, r#type) = crate::extension::read_ext_header(format, reader)?;
120 reader
121 .read_slice(length)
122 .map_err(Error::Io)
123 .map(|data| match data {
124 crate::io::Reference::Borrowed(items) => Any::ExtBorrowed {
125 r#type,
126 data: items,
127 },
128 crate::io::Reference::Copied(items) => Any::ExtCopied {
129 r#type,
130 len: items.len(),
131 },
132 })
133 }
134 Format::FixArray(_) | Format::Array16 | Format::Array32 => {
135 ArrayDecoder::<IterCounter, Any>::decode_with_format(format, reader)
136 .map(|counter| Any::Array(counter.count))
137 }
138
139 Format::FixMap(_) | Format::Map16 | Format::Map32 => {
140 MapDecoder::<IterCounter, Any, Any>::decode_with_format(format, reader)
141 .map(|counter| Any::Map(counter.count))
142 }
143 Format::NeverUsed => Err(Error::UnexpectedFormat),
144 }
145 }
146}
147
148struct IterCounter {
149 count: usize,
150}
151
152impl<'de> FromIterator<Any<'de>> for IterCounter {
153 fn from_iter<T: IntoIterator<Item = Any<'de>>>(iter: T) -> Self {
154 let count = iter.into_iter().count();
155 Self { count }
156 }
157}
158
159impl<'de> FromIterator<(Any<'de>, Any<'de>)> for IterCounter {
160 fn from_iter<T: IntoIterator<Item = (Any<'de>, Any<'de>)>>(iter: T) -> Self {
161 let count = iter.into_iter().count();
162 Self { count }
163 }
164}
165
166#[cfg(test)]
167mod tests {
168 use super::*;
169 use rstest::rstest;
170
171 #[rstest]
172 #[case(&[0xc0], Any::Nil)]
174 #[case(&[0xc2], Any::Bool(false))]
176 #[case(&[0xc3], Any::Bool(true))]
177 #[case(&[0x00], Any::U8(0))]
179 #[case(&[0x7f], Any::U8(127))]
180 #[case(&[0xcc, 0x80], Any::U8(128))]
182 #[case(&[0xcc, 0xff], Any::U8(255))]
183 #[case(&[0xcd, 0x01, 0x00], Any::U16(256))]
185 #[case(&[0xcd, 0xff, 0xff], Any::U16(65535))]
186 #[case(&[0xce, 0x00, 0x01, 0x00, 0x00], Any::U32(65536))]
188 #[case(&[0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00], Any::U64(4294967296))]
190 #[case(&[0xff], Any::I8(-1))]
192 #[case(&[0xe0], Any::I8(-32))]
193 #[case(&[0xd0, 0xdf], Any::I8(-33))]
195 #[case(&[0xd0, 0x80], Any::I8(-128))]
196 #[case(&[0xd1, 0xff, 0x00], Any::I16(-256))]
198 #[case(&[0xd1, 0x80, 0x00], Any::I16(-32768))]
199 #[case(&[0xd2, 0xff, 0xff, 0x00, 0x00], Any::I32(-65536))]
201 #[case(&[0xd3, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00], Any::I64(-4294967296))]
203 #[case(&[0xca, 0x41, 0x20, 0x00, 0x00], Any::F32(10.0))]
205 #[case(&[0xcb, 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Any::F64(10.0))]
207 #[case(&[0xa0], Any::StrBorrowed(""))]
209 #[case(&[0xa2, 0x68, 0x69], Any::StrBorrowed("hi"))]
211 #[case(&[0xd9, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f], Any::StrBorrowed("hello"))]
213 #[case(&[0xc4, 0x00], Any::BinBorrowed(&[]))]
215 #[case(&[0xc4, 0x03, 0x01, 0x02, 0x03], Any::BinBorrowed(&[1, 2, 3]))]
217 #[case(&[0x90], Any::Array(0))]
219 #[case(&[0x92, 0xc0, 0xc3], Any::Array(2))]
221 #[case(&[0x91, 0x91, 0xc0], Any::Array(1))]
223 #[case(&[0x80], Any::Map(0))]
225 #[case(&[0x81, 0x01, 0xc3], Any::Map(1))]
227 #[case(&[0xd4, 0x01, 0xaa], Any::ExtBorrowed { r#type: 1, data: &[0xaa] })]
229 #[case(&[0xd5, 0x02, 0xaa, 0xbb], Any::ExtBorrowed { r#type: 2, data: &[0xaa, 0xbb] })]
231 #[case(&[0xd6, 0x03, 0x01, 0x02, 0x03, 0x04], Any::ExtBorrowed { r#type: 3, data: &[1, 2, 3, 4] })]
233 #[case(&[0xc7, 0x00, 0x05], Any::ExtBorrowed { r#type: 5, data: &[] })]
235 #[case(&[0xc7, 0x03, 0x0a, 0x01, 0x02, 0x03], Any::ExtBorrowed { r#type: 10, data: &[1, 2, 3] })]
237 fn decode_any_ok(#[case] input: &[u8], #[case] expected: Any<'_>) {
239 let mut reader = crate::io::SliceReader::new(input);
240 let value = Any::decode(&mut reader).unwrap();
241 assert_eq!(value, expected);
242 }
243 #[rstest]
244 #[case::never_used(&[0xc1])]
245 fn decode_any_err(#[case] input: &[u8]) {
246 let mut reader = crate::io::SliceReader::new(input);
247 assert!(Any::decode(&mut reader).is_err());
248 }
249}