scuffle_amf0/
value.rs

1//! AMF0 value types.
2
3use std::io;
4
5use scuffle_bytes_util::StringCow;
6use serde::de::IntoDeserializer;
7
8use crate::Amf0Error;
9use crate::encoder::Amf0Encoder;
10use crate::object::Amf0Object;
11
12/// Represents any AMF0 value.
13#[derive(Debug, PartialEq, Clone)]
14pub enum Amf0Value<'a> {
15    /// AMF0 Number.
16    Number(f64),
17    /// AMF0 Boolean.
18    Boolean(bool),
19    /// AMF0 String.
20    String(StringCow<'a>),
21    /// AMF0 Object.
22    Object(Amf0Object<'a>),
23    /// AMF0 Null.
24    Null,
25    /// AMF0 Array.
26    Array(Vec<Amf0Value<'a>>),
27}
28
29impl Amf0Value<'_> {
30    /// Converts this AMF0 value into an owned version (static lifetime).
31    pub fn into_owned(self) -> Amf0Value<'static> {
32        match self {
33            Amf0Value::Number(v) => Amf0Value::Number(v),
34            Amf0Value::Boolean(v) => Amf0Value::Boolean(v),
35            Amf0Value::String(v) => Amf0Value::String(v.into_owned()),
36            Amf0Value::Object(v) => {
37                Amf0Value::Object(v.into_iter().map(|(k, v)| (k.into_owned(), v.into_owned())).collect())
38            }
39            Amf0Value::Null => Amf0Value::Null,
40            Amf0Value::Array(v) => Amf0Value::Array(v.into_iter().map(|v| v.into_owned()).collect()),
41        }
42    }
43
44    /// Encode this AMF0 value with the given encoder.
45    pub fn encode<W: io::Write>(&self, encoder: &mut Amf0Encoder<W>) -> Result<(), Amf0Error> {
46        match self {
47            Amf0Value::Number(v) => encoder.encode_number(*v),
48            Amf0Value::Boolean(v) => encoder.encode_boolean(*v),
49            Amf0Value::String(v) => encoder.encode_string(v.as_str()),
50            Amf0Value::Object(v) => encoder.encode_object(v),
51            Amf0Value::Null => encoder.encode_null(),
52            Amf0Value::Array(v) => encoder.encode_array(v),
53        }
54    }
55}
56
57impl From<f64> for Amf0Value<'_> {
58    fn from(value: f64) -> Self {
59        Amf0Value::Number(value)
60    }
61}
62
63impl From<bool> for Amf0Value<'_> {
64    fn from(value: bool) -> Self {
65        Amf0Value::Boolean(value)
66    }
67}
68
69impl<'a> From<StringCow<'a>> for Amf0Value<'a> {
70    fn from(value: StringCow<'a>) -> Self {
71        Amf0Value::String(value)
72    }
73}
74
75// object
76impl<'a> From<Amf0Object<'a>> for Amf0Value<'a> {
77    fn from(value: Amf0Object<'a>) -> Self {
78        Amf0Value::Object(value)
79    }
80}
81
82// owned array
83impl<'a> From<Vec<Amf0Value<'a>>> for Amf0Value<'a> {
84    fn from(value: Vec<Amf0Value<'a>>) -> Self {
85        Amf0Value::Array(value)
86    }
87}
88
89impl<'a> FromIterator<Amf0Value<'a>> for Amf0Value<'a> {
90    fn from_iter<T: IntoIterator<Item = Amf0Value<'a>>>(iter: T) -> Self {
91        Amf0Value::Array(iter.into_iter().collect())
92    }
93}
94
95#[cfg(feature = "serde")]
96impl<'de> serde::de::Deserialize<'de> for Amf0Value<'de> {
97    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
98    where
99        D: serde::Deserializer<'de>,
100    {
101        struct Amf0ValueVisitor;
102
103        impl<'de> serde::de::Visitor<'de> for Amf0ValueVisitor {
104            type Value = Amf0Value<'de>;
105
106            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
107                formatter.write_str("an AMF0 value")
108            }
109
110            #[inline]
111            fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
112            where
113                E: serde::de::Error,
114            {
115                Ok(Amf0Value::Boolean(v))
116            }
117
118            #[inline]
119            fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
120            where
121                E: serde::de::Error,
122            {
123                self.visit_f64(v as f64)
124            }
125
126            #[inline]
127            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
128            where
129                E: serde::de::Error,
130            {
131                self.visit_f64(v as f64)
132            }
133
134            #[inline]
135            fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
136            where
137                E: serde::de::Error,
138            {
139                Ok(Amf0Value::Number(v))
140            }
141
142            #[inline]
143            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
144            where
145                E: serde::de::Error,
146            {
147                self.visit_string(v.to_owned())
148            }
149
150            #[inline]
151            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
152            where
153                E: serde::de::Error,
154            {
155                Ok(StringCow::from(v).into())
156            }
157
158            #[inline]
159            fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
160            where
161                E: serde::de::Error,
162            {
163                Ok(StringCow::from(v).into())
164            }
165
166            #[inline]
167            fn visit_unit<E>(self) -> Result<Self::Value, E>
168            where
169                E: serde::de::Error,
170            {
171                Ok(Amf0Value::Null)
172            }
173
174            #[inline]
175            fn visit_none<E>(self) -> Result<Self::Value, E>
176            where
177                E: serde::de::Error,
178            {
179                Ok(Amf0Value::Null)
180            }
181
182            #[inline]
183            fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
184            where
185                D: serde::Deserializer<'de>,
186            {
187                serde::Deserialize::deserialize(deserializer)
188            }
189
190            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
191            where
192                A: serde::de::SeqAccess<'de>,
193            {
194                let mut vec = Vec::new();
195
196                while let Some(value) = seq.next_element()? {
197                    vec.push(value);
198                }
199
200                Ok(vec.into())
201            }
202
203            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
204            where
205                A: serde::de::MapAccess<'de>,
206            {
207                use crate::object::Amf0Object;
208
209                let mut object = Amf0Object::new();
210
211                while let Some((key, value)) = map.next_entry()? {
212                    object.insert(key, value);
213                }
214
215                Ok(object.into())
216            }
217
218            fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
219            where
220                E: serde::de::Error,
221            {
222                let array = v.iter().map(|b| Amf0Value::Number(*b as f64)).collect();
223                Ok(Amf0Value::Array(array))
224            }
225        }
226
227        deserializer.deserialize_any(Amf0ValueVisitor)
228    }
229}
230
231#[cfg(feature = "serde")]
232impl serde::ser::Serialize for Amf0Value<'_> {
233    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
234    where
235        S: serde::Serializer,
236    {
237        match self {
238            Amf0Value::Number(v) => serializer.serialize_f64(*v),
239            Amf0Value::Boolean(v) => serializer.serialize_bool(*v),
240            Amf0Value::String(v) => v.serialize(serializer),
241            Amf0Value::Object(v) => {
242                let mut map = serializer.serialize_map(Some(v.len()))?;
243
244                for (key, value) in v.iter() {
245                    serde::ser::SerializeMap::serialize_entry(&mut map, key, value)?;
246                }
247
248                serde::ser::SerializeMap::end(map)
249            }
250            Amf0Value::Null => serializer.serialize_none(),
251            Amf0Value::Array(v) => {
252                let mut seq = serializer.serialize_seq(Some(v.len()))?;
253
254                for value in v.iter() {
255                    serde::ser::SerializeSeq::serialize_element(&mut seq, value)?;
256                }
257
258                serde::ser::SerializeSeq::end(seq)
259            }
260        }
261    }
262}
263
264#[cfg(feature = "serde")]
265macro_rules! impl_de_number {
266    ($deserializser_fn:ident, $visit_fn:ident) => {
267        fn $deserializser_fn<V>(self, visitor: V) -> Result<V::Value, Self::Error>
268        where
269            V: serde::de::Visitor<'de>,
270        {
271            if let Amf0Value::Number(n) = self {
272                let n = *(&n as &f64);
273                if let Some(n) = ::num_traits::cast(n) {
274                    visitor.$visit_fn(n)
275                } else {
276                    visitor.visit_f64(n)
277                }
278            } else {
279                self.deserialize_any(visitor)
280            }
281        }
282    };
283}
284
285#[cfg(feature = "serde")]
286macro_rules! impl_deserializer {
287    ($ty:ty) => {
288        impl<'de> serde::Deserializer<'de> for $ty {
289            type Error = Amf0Error;
290
291            serde::forward_to_deserialize_any! {
292                bool f64 str string unit
293                seq map newtype_struct tuple
294                struct enum ignored_any identifier
295                unit_struct tuple_struct
296            }
297
298            impl_de_number!(deserialize_i8, visit_i8);
299
300            impl_de_number!(deserialize_i16, visit_i16);
301
302            impl_de_number!(deserialize_i32, visit_i32);
303
304            impl_de_number!(deserialize_i64, visit_i64);
305
306            impl_de_number!(deserialize_u8, visit_u8);
307
308            impl_de_number!(deserialize_u16, visit_u16);
309
310            impl_de_number!(deserialize_u32, visit_u32);
311
312            impl_de_number!(deserialize_u64, visit_u64);
313
314            impl_de_number!(deserialize_f32, visit_f32);
315
316            fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
317            where
318                V: serde::de::Visitor<'de>,
319            {
320                if let Amf0Value::String(s) = self {
321                    s.into_deserializer().deserialize_any(visitor)
322                } else {
323                    self.deserialize_any(visitor)
324                }
325            }
326
327            fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
328            where
329                V: serde::de::Visitor<'de>,
330            {
331                match self {
332                    Amf0Value::Null => visitor.visit_none(),
333                    _ => visitor.visit_some(self),
334                }
335            }
336
337            fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
338            where
339                V: serde::de::Visitor<'de>,
340            {
341                if let Amf0Value::Array(a) = &self {
342                    match a
343                        .iter()
344                        .map(|a| match a {
345                            Amf0Value::Number(n) => num_traits::cast(*n).ok_or(()),
346                            _ => Err(()),
347                        })
348                        .collect::<Result<_, _>>()
349                    {
350                        Ok(buf) => visitor.visit_byte_buf(buf),
351                        Err(()) => self.deserialize_any(visitor),
352                    }
353                } else {
354                    self.deserialize_any(visitor)
355                }
356            }
357
358            fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
359            where
360                V: serde::de::Visitor<'de>,
361            {
362                self.deserialize_seq(visitor)
363            }
364
365            fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
366            where
367                V: serde::de::Visitor<'de>,
368            {
369                match self {
370                    Amf0Value::Null => visitor.visit_unit(),
371                    Amf0Value::Boolean(b) => visitor.visit_bool(*(&b as &bool)),
372                    Amf0Value::Number(n) => visitor.visit_f64(*(&n as &f64)),
373                    Amf0Value::String(s) => s.into_deserializer().deserialize_any(visitor),
374                    Amf0Value::Array(a) => visitor.visit_seq(Amf0SeqAccess { iter: a.into_iter() }),
375                    Amf0Value::Object(o) => o.into_deserializer().deserialize_any(visitor),
376                }
377            }
378        }
379    };
380}
381
382#[cfg(feature = "serde")]
383impl_deserializer!(Amf0Value<'de>);
384#[cfg(feature = "serde")]
385impl_deserializer!(&'de Amf0Value<'de>);
386
387#[cfg(feature = "serde")]
388impl<'de> serde::de::IntoDeserializer<'de, Amf0Error> for Amf0Value<'de> {
389    type Deserializer = Amf0Value<'de>;
390
391    fn into_deserializer(self) -> Self::Deserializer {
392        self
393    }
394}
395
396#[cfg(feature = "serde")]
397impl<'de> serde::de::IntoDeserializer<'de, Amf0Error> for &'de Amf0Value<'de> {
398    type Deserializer = &'de Amf0Value<'de>;
399
400    fn into_deserializer(self) -> Self::Deserializer {
401        self
402    }
403}
404
405#[cfg(feature = "serde")]
406struct Amf0SeqAccess<I> {
407    iter: I,
408}
409
410#[cfg(feature = "serde")]
411impl<'de, I> serde::de::SeqAccess<'de> for Amf0SeqAccess<I>
412where
413    I: Iterator,
414    I::Item: serde::de::IntoDeserializer<'de, Amf0Error>,
415{
416    type Error = Amf0Error;
417
418    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
419    where
420        T: serde::de::DeserializeSeed<'de>,
421    {
422        match self.iter.next() {
423            Some(value) => seed.deserialize(value.into_deserializer()).map(Some),
424            None => Ok(None),
425        }
426    }
427}
428
429#[cfg(test)]
430#[cfg_attr(all(test, coverage_nightly), coverage(off))]
431mod tests {
432    use std::collections::HashMap;
433
434    use scuffle_bytes_util::StringCow;
435    #[cfg(feature = "serde")]
436    use serde::Deserialize;
437    use serde::Serialize;
438
439    use super::Amf0Value;
440    use crate::{Amf0Decoder, Amf0Encoder, Amf0Error, Amf0Marker, Amf0Object};
441
442    #[test]
443    fn from() {
444        let value: Amf0Value = 1.0.into();
445        assert_eq!(value, Amf0Value::Number(1.0));
446
447        let value: Amf0Value = true.into();
448        assert_eq!(value, Amf0Value::Boolean(true));
449
450        let value: Amf0Value = StringCow::from("abc").into();
451        assert_eq!(value, Amf0Value::String("abc".into()));
452
453        let object: Amf0Object = [("a".into(), Amf0Value::Boolean(true))].into_iter().collect();
454        let value: Amf0Value = object.clone().into();
455        assert_eq!(value, Amf0Value::Object(object));
456
457        let array: Vec<Amf0Value> = vec![Amf0Value::Boolean(true)];
458        let value: Amf0Value = array.clone().into();
459        assert_eq!(value, Amf0Value::Array(array));
460
461        let iter = std::iter::once(Amf0Value::Boolean(true));
462        let value: Amf0Value = iter.collect();
463        assert_eq!(value, Amf0Value::Array(vec![Amf0Value::Boolean(true)]));
464    }
465
466    #[test]
467    fn unsupported_marker() {
468        let bytes = [Amf0Marker::MovieClipMarker as u8];
469
470        let err = Amf0Decoder::from_slice(&bytes).decode_value().unwrap_err();
471        assert!(matches!(err, Amf0Error::UnsupportedMarker(Amf0Marker::MovieClipMarker)));
472    }
473
474    #[test]
475    fn string() {
476        use crate::Amf0Decoder;
477
478        #[rustfmt::skip]
479        let bytes = [
480            Amf0Marker::String as u8,
481            0, 3, // length
482            b'a', b'b', b'c',
483        ];
484
485        let value = Amf0Decoder::from_slice(&bytes).decode_value().unwrap();
486        assert_eq!(value, Amf0Value::String("abc".into()));
487    }
488
489    #[test]
490    fn bool() {
491        let bytes = [Amf0Marker::Boolean as u8, 0];
492
493        let value = Amf0Decoder::from_slice(&bytes).decode_value().unwrap();
494        assert_eq!(value, Amf0Value::Boolean(false));
495    }
496
497    #[test]
498    fn object() {
499        #[rustfmt::skip]
500        let bytes = [
501            Amf0Marker::Object as u8,
502            0, 1,
503            b'a',
504            Amf0Marker::Boolean as u8,
505            1,
506            0, 0, Amf0Marker::ObjectEnd as u8,
507        ];
508
509        let value = Amf0Decoder::from_slice(&bytes).decode_value().unwrap();
510        assert_eq!(
511            value,
512            Amf0Value::Object([("a".into(), Amf0Value::Boolean(true))].into_iter().collect())
513        );
514    }
515
516    #[test]
517    fn array() {
518        #[rustfmt::skip]
519        let bytes = [
520            Amf0Marker::StrictArray as u8,
521            0, 0, 0, 1,
522            Amf0Marker::Boolean as u8,
523            1,
524        ];
525
526        let value = Amf0Decoder::from_slice(&bytes).decode_value().unwrap();
527        assert_eq!(value, Amf0Value::Array(vec![Amf0Value::Boolean(true)]));
528
529        let mut serialized = vec![];
530        value.encode(&mut Amf0Encoder::new(&mut serialized)).unwrap();
531        assert_eq!(serialized, bytes);
532    }
533
534    #[test]
535    fn null() {
536        let bytes = [Amf0Marker::Null as u8];
537
538        let value = Amf0Decoder::from_slice(&bytes).decode_value().unwrap();
539        assert_eq!(value, Amf0Value::Null);
540
541        let mut serialized = vec![];
542        value.encode(&mut Amf0Encoder::new(&mut serialized)).unwrap();
543        assert_eq!(serialized, bytes);
544    }
545
546    #[test]
547    fn into_owned() {
548        let value = Amf0Value::Number(1.0);
549        let owned_value = value.clone().into_owned();
550        assert_eq!(owned_value, value);
551
552        let value = Amf0Value::Boolean(true);
553        let owned_value = value.clone().into_owned();
554        assert_eq!(owned_value, value);
555
556        let value = Amf0Value::String("abc".into());
557        let owned_value = value.clone().into_owned();
558        assert_eq!(owned_value, value);
559
560        let value = Amf0Value::Object([("a".into(), Amf0Value::Boolean(true))].into_iter().collect());
561        let owned_value = value.clone().into_owned();
562        assert_eq!(owned_value, value,);
563
564        let value = Amf0Value::Null;
565        let owned_value = value.clone().into_owned();
566        assert_eq!(owned_value, value);
567
568        let value = Amf0Value::Array(vec![Amf0Value::Boolean(true)]);
569        let owned_value = value.clone().into_owned();
570        assert_eq!(owned_value, value);
571    }
572
573    #[cfg(feature = "serde")]
574    #[test]
575    fn deserialize() {
576        use std::fmt::Display;
577
578        use serde::Deserialize;
579        use serde::de::{IntoDeserializer, MapAccess, SeqAccess};
580
581        #[derive(Debug)]
582        struct TestError;
583
584        impl Display for TestError {
585            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
586                write!(f, "Test error")
587            }
588        }
589
590        impl std::error::Error for TestError {}
591
592        impl serde::de::Error for TestError {
593            fn custom<T: std::fmt::Display>(msg: T) -> Self {
594                assert_eq!(msg.to_string(), "invalid type: Option value, expected a byte slice");
595                Self
596            }
597        }
598
599        enum Mode {
600            Bool,
601            I64,
602            U64,
603            F64,
604            Str,
605            String,
606            BorrowedStr,
607            Unit,
608            None,
609            Some,
610            Seq,
611            Map,
612            Bytes,
613            End,
614        }
615
616        struct TestDeserializer {
617            mode: Mode,
618        }
619
620        impl<'de> SeqAccess<'de> for TestDeserializer {
621            type Error = TestError;
622
623            fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
624            where
625                T: serde::de::DeserializeSeed<'de>,
626            {
627                match self.mode {
628                    Mode::Seq => {
629                        self.mode = Mode::End;
630                        Ok(Some(seed.deserialize(TestDeserializer { mode: Mode::I64 })?))
631                    }
632                    Mode::End => Ok(None),
633                    _ => Err(TestError),
634                }
635            }
636        }
637
638        impl<'de> MapAccess<'de> for TestDeserializer {
639            type Error = TestError;
640
641            fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
642            where
643                K: serde::de::DeserializeSeed<'de>,
644            {
645                match self.mode {
646                    Mode::Map => Ok(Some(seed.deserialize(TestDeserializer { mode: Mode::Str })?)),
647                    Mode::End => Ok(None),
648                    _ => Err(TestError),
649                }
650            }
651
652            fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
653            where
654                V: serde::de::DeserializeSeed<'de>,
655            {
656                match self.mode {
657                    Mode::Map => {
658                        self.mode = Mode::End;
659                        Ok(seed.deserialize(TestDeserializer { mode: Mode::I64 })?)
660                    }
661                    _ => Err(TestError),
662                }
663            }
664        }
665
666        impl<'de> serde::Deserializer<'de> for TestDeserializer {
667            type Error = TestError;
668
669            serde::forward_to_deserialize_any! {
670                bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf
671                option unit unit_struct newtype_struct seq tuple tuple_struct
672                map struct enum identifier ignored_any
673            }
674
675            fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
676            where
677                V: serde::de::Visitor<'de>,
678            {
679                match self.mode {
680                    Mode::Bool => visitor.visit_bool(true),
681                    Mode::I64 => visitor.visit_i64(1),
682                    Mode::U64 => visitor.visit_u64(1),
683                    Mode::F64 => visitor.visit_f64(1.0),
684                    Mode::Str => visitor.visit_str("hello"),
685                    Mode::String => visitor.visit_string("hello".to_owned()),
686                    Mode::BorrowedStr => visitor.visit_borrowed_str("hello"),
687                    Mode::Unit => visitor.visit_unit(),
688                    Mode::None => visitor.visit_none(),
689                    Mode::Some => visitor.visit_some(1.into_deserializer()),
690                    Mode::Seq => visitor.visit_seq(self),
691                    Mode::Map => visitor.visit_map(self),
692                    Mode::Bytes => visitor.visit_bytes(b"hello"),
693                    Mode::End => unreachable!(),
694                }
695            }
696        }
697
698        fn test_de(mode: Mode, expected: Amf0Value) {
699            let deserializer = TestDeserializer { mode };
700            let deserialized_value: Amf0Value = Amf0Value::deserialize(deserializer).unwrap();
701            assert_eq!(deserialized_value, expected);
702        }
703
704        test_de(Mode::Bool, Amf0Value::Boolean(true));
705        test_de(Mode::I64, Amf0Value::Number(1.0));
706        test_de(Mode::U64, Amf0Value::Number(1.0));
707        test_de(Mode::F64, Amf0Value::Number(1.0));
708        test_de(Mode::Str, Amf0Value::String("hello".into()));
709        test_de(Mode::String, Amf0Value::String("hello".into()));
710        test_de(Mode::BorrowedStr, Amf0Value::String("hello".into()));
711        test_de(Mode::Unit, Amf0Value::Null);
712        test_de(Mode::None, Amf0Value::Null);
713        test_de(Mode::Some, Amf0Value::Number(1.0));
714        test_de(Mode::Seq, Amf0Value::Array(vec![Amf0Value::Number(1.0)]));
715        test_de(
716            Mode::Map,
717            Amf0Value::Object([("hello".into(), Amf0Value::Number(1.0))].into_iter().collect()),
718        );
719        test_de(
720            Mode::Bytes,
721            Amf0Value::Array(vec![
722                Amf0Value::Number(104.0),
723                Amf0Value::Number(101.0),
724                Amf0Value::Number(108.0),
725                Amf0Value::Number(108.0),
726                Amf0Value::Number(111.0),
727            ]),
728        );
729    }
730
731    #[cfg(feature = "serde")]
732    #[test]
733    fn deserialize_bool() {
734        let value = Amf0Value::Boolean(true);
735        let deserialized: bool = Deserialize::deserialize(value).unwrap();
736        assert!(deserialized);
737    }
738
739    #[cfg(feature = "serde")]
740    #[test]
741    fn deserialize_number() {
742        let value = Amf0Value::Number(42.0);
743        let deserialized: f64 = Deserialize::deserialize(value).unwrap();
744        assert_eq!(deserialized, 42.0);
745    }
746
747    #[cfg(feature = "serde")]
748    #[test]
749    fn deserialize_string() {
750        let value = Amf0Value::String(StringCow::from("hello"));
751        let deserialized: String = Deserialize::deserialize(value).unwrap();
752        assert_eq!(deserialized, "hello");
753    }
754
755    #[cfg(feature = "serde")]
756    #[test]
757    fn deserialize_null() {
758        let value = Amf0Value::Null;
759        let deserialized: Option<i32> = Deserialize::deserialize(value).unwrap();
760        assert_eq!(deserialized, None);
761    }
762
763    #[cfg(feature = "serde")]
764    #[test]
765    fn deserialize_array() {
766        let value = Amf0Value::Array(vec![Amf0Value::Number(1.0), Amf0Value::Number(2.0), Amf0Value::Number(3.0)]);
767
768        let deserialized: Vec<f64> = Deserialize::deserialize(value).unwrap();
769        assert_eq!(deserialized, vec![1.0, 2.0, 3.0]);
770    }
771
772    #[cfg(feature = "serde")]
773    #[test]
774    fn deserialize_object() {
775        use std::collections::HashMap;
776
777        let mut map = Amf0Object::new();
778        map.insert(StringCow::from("key"), Amf0Value::String(StringCow::from("value")));
779        let value = Amf0Value::Object(map);
780
781        let deserialized: HashMap<String, String> = Deserialize::deserialize(value).unwrap();
782        assert_eq!(deserialized.get("key"), Some(&"value".to_string()));
783    }
784
785    #[cfg(feature = "serde")]
786    #[test]
787    fn deserialize_complex_structure() {
788        let value = Amf0Value::Object(Amf0Object::from_iter([
789            (
790                StringCow::from("numbers"),
791                Amf0Value::Array(vec![Amf0Value::Number(1.0), Amf0Value::Number(2.0)]),
792            ),
793            (StringCow::from("flag"), Amf0Value::Boolean(true)),
794        ]));
795
796        #[derive(Debug, Deserialize, PartialEq)]
797        struct Complex {
798            numbers: Vec<f64>,
799            flag: bool,
800        }
801
802        let deserialized: Complex = Deserialize::deserialize(value).unwrap();
803
804        assert_eq!(
805            deserialized,
806            Complex {
807                numbers: vec![1.0, 2.0],
808                flag: true
809            }
810        );
811    }
812
813    #[test]
814    fn roundtrip_number() {
815        let original: f64 = 3.22;
816        let mut buf = Vec::new();
817
818        {
819            let mut encoder = Amf0Encoder::new(&mut buf);
820            original.serialize(&mut encoder).unwrap();
821        }
822
823        let decoded_value = Amf0Decoder::from_slice(&buf).decode_value().unwrap();
824        let decoded_native: f64 = Amf0Decoder::from_slice(&buf).deserialize().unwrap();
825        let decoded_value_native: f64 = Deserialize::deserialize(decoded_value.clone()).unwrap();
826        assert_eq!(original, decoded_native);
827        assert_eq!(original, decoded_value_native);
828
829        let mut buf2 = Vec::new();
830        {
831            let mut encoder = Amf0Encoder::new(&mut buf2);
832            decoded_value.serialize(&mut encoder).unwrap();
833        }
834
835        assert_eq!(buf, buf2);
836    }
837
838    #[test]
839    fn roundtrip_boolean() {
840        let original: bool = true;
841        let mut buf = Vec::new();
842        {
843            let mut encoder = Amf0Encoder::new(&mut buf);
844            original.serialize(&mut encoder).unwrap();
845        }
846        let decoded_value = Amf0Decoder::from_slice(&buf).decode_value().unwrap();
847        let decoded_native: bool = Amf0Decoder::from_slice(&buf).deserialize().unwrap();
848        let decoded_value_native: bool = Deserialize::deserialize(decoded_value.clone()).unwrap();
849        assert_eq!(original, decoded_native);
850        assert_eq!(original, decoded_value_native);
851        let mut buf2 = Vec::new();
852        {
853            let mut encoder = Amf0Encoder::new(&mut buf2);
854            decoded_value.serialize(&mut encoder).unwrap();
855        }
856        assert_eq!(buf, buf2);
857    }
858
859    #[test]
860    fn roundtrip_string() {
861        let original: String = "hello".to_string();
862        let mut buf = Vec::new();
863        {
864            let mut encoder = Amf0Encoder::new(&mut buf);
865            original.serialize(&mut encoder).unwrap();
866        }
867        let decoded_value = Amf0Decoder::from_slice(&buf).decode_value().unwrap();
868        let decoded_native: String = Amf0Decoder::from_slice(&buf).deserialize().unwrap();
869        let decoded_value_native: String = Deserialize::deserialize(decoded_value.clone()).unwrap();
870        assert_eq!(original, decoded_native);
871        assert_eq!(original, decoded_value_native);
872        let mut buf2 = Vec::new();
873        {
874            let mut encoder = Amf0Encoder::new(&mut buf2);
875            decoded_value.serialize(&mut encoder).unwrap();
876        }
877        assert_eq!(buf, buf2);
878    }
879
880    #[test]
881    fn roundtrip_null() {
882        let original: Option<bool> = None;
883        let mut buf = Vec::new();
884        {
885            let mut encoder = Amf0Encoder::new(&mut buf);
886            original.serialize(&mut encoder).unwrap();
887        }
888        let decoded_value = Amf0Decoder::from_slice(&buf).decode_value().unwrap();
889        let decoded_native: Option<bool> = Amf0Decoder::from_slice(&buf).deserialize().unwrap();
890        let decoded_value_native: Option<bool> = Deserialize::deserialize(decoded_value.clone()).unwrap();
891        assert_eq!(original, decoded_native);
892        assert_eq!(original, decoded_value_native);
893        let mut buf2 = Vec::new();
894        {
895            let mut encoder = Amf0Encoder::new(&mut buf2);
896            decoded_value.serialize(&mut encoder).unwrap();
897        }
898        assert_eq!(buf, buf2);
899    }
900
901    #[test]
902    fn roundtrip_array() {
903        let original: Vec<f64> = vec![1.0, 2.0, 3.0];
904        let mut buf = Vec::new();
905        {
906            let mut encoder = Amf0Encoder::new(&mut buf);
907            original.serialize(&mut encoder).unwrap();
908        }
909        let decoded_value = Amf0Decoder::from_slice(&buf).decode_value().unwrap();
910        let decoded_native: Vec<f64> = Amf0Decoder::from_slice(&buf).deserialize().unwrap();
911        let decoded_value_native: Vec<f64> = Deserialize::deserialize(decoded_value.clone()).unwrap();
912        assert_eq!(original, decoded_native);
913        assert_eq!(original, decoded_value_native);
914        let mut buf2 = Vec::new();
915        {
916            let mut encoder = Amf0Encoder::new(&mut buf2);
917            decoded_value.serialize(&mut encoder).unwrap();
918        }
919        assert_eq!(buf, buf2);
920    }
921
922    #[test]
923    fn roundtrip_map() {
924        let mut original: HashMap<String, String> = HashMap::new();
925        original.insert("key".to_string(), "val".to_string());
926        let mut buf = Vec::new();
927        {
928            let mut encoder = Amf0Encoder::new(&mut buf);
929            original.serialize(&mut encoder).unwrap();
930        }
931        let decoded_value = Amf0Decoder::from_slice(&buf).decode_value().unwrap();
932        let decoded_native: HashMap<String, String> = Amf0Decoder::from_slice(&buf).deserialize().unwrap();
933        let decoded_value_native: HashMap<String, String> = Deserialize::deserialize(decoded_value.clone()).unwrap();
934        assert_eq!(original, decoded_native);
935        assert_eq!(original, decoded_value_native);
936        let mut buf2 = Vec::new();
937        {
938            let mut encoder = Amf0Encoder::new(&mut buf2);
939            decoded_value.serialize(&mut encoder).unwrap();
940        }
941        assert_eq!(buf, buf2);
942    }
943
944    #[derive(Serialize, Deserialize, PartialEq, Debug)]
945    struct TestStruct { x: i32, y: String }
946
947    #[test]
948    fn roundtrip_struct() {
949        let original = TestStruct { x: 42, y: "foo".to_string() };
950        let mut buf = Vec::new();
951        {
952            let mut encoder = Amf0Encoder::new(&mut buf);
953            original.serialize(&mut encoder).unwrap();
954        }
955        let decoded_value = Amf0Decoder::from_slice(&buf).decode_value().unwrap();
956        let decoded_native: TestStruct = Amf0Decoder::from_slice(&buf).deserialize().unwrap();
957        let decoded_value_native: TestStruct = Deserialize::deserialize(decoded_value.clone()).unwrap();
958        assert_eq!(original, decoded_native);
959        assert_eq!(original, decoded_value_native);
960        let mut buf2 = Vec::new();
961        {
962            let mut encoder = Amf0Encoder::new(&mut buf2);
963            decoded_value.serialize(&mut encoder).unwrap();
964        }
965        assert_eq!(buf, buf2);
966    }
967
968    #[derive(Serialize, Deserialize, PartialEq, Debug)]
969    enum TestEnum { Unit, NewType(i16), Struct { name: String } }
970
971    #[test]
972    fn roundtrip_enum_unit() {
973        let original = TestEnum::Unit;
974        let mut buf = Vec::new();
975        {
976            let mut encoder = Amf0Encoder::new(&mut buf);
977            original.serialize(&mut encoder).unwrap();
978        }
979        let decoded_value = Amf0Decoder::from_slice(&buf).decode_value().unwrap();
980        let decoded_native: TestEnum = Amf0Decoder::from_slice(&buf).deserialize().unwrap();
981        let decoded_value_native: TestEnum = Deserialize::deserialize(decoded_value.clone()).unwrap();
982        assert_eq!(original, decoded_native);
983        assert_eq!(original, decoded_value_native);
984        let mut buf2 = Vec::new();
985        {
986            let mut encoder = Amf0Encoder::new(&mut buf2);
987            decoded_value.serialize(&mut encoder).unwrap();
988        }
989        assert_eq!(buf, buf2);
990    }
991
992    #[test]
993    fn roundtrip_enum_newtype() {
994        let original = TestEnum::NewType(7);
995        let mut buf = Vec::new();
996        {
997            let mut encoder = Amf0Encoder::new(&mut buf);
998            original.serialize(&mut encoder).unwrap();
999        }
1000        let decoded_value = Amf0Decoder::from_slice(&buf).decode_value().unwrap();
1001        let decoded_native: TestEnum = Amf0Decoder::from_slice(&buf).deserialize().unwrap();
1002        let decoded_value_native: TestEnum = Deserialize::deserialize(decoded_value.clone()).unwrap();
1003        assert_eq!(original, decoded_native);
1004        assert_eq!(original, decoded_value_native);
1005        let mut buf2 = Vec::new();
1006        {
1007            let mut encoder = Amf0Encoder::new(&mut buf2);
1008            decoded_value.serialize(&mut encoder).unwrap();
1009        }
1010        assert_eq!(buf, buf2);
1011    }
1012
1013    #[test]
1014    fn roundtrip_enum_struct() {
1015        let original = TestEnum::Struct { name: "bar".to_string() };
1016        let mut buf = Vec::new();
1017        {
1018            let mut encoder = Amf0Encoder::new(&mut buf);
1019            original.serialize(&mut encoder).unwrap();
1020        }
1021        let decoded_value = Amf0Decoder::from_slice(&buf).decode_value().unwrap();
1022        let decoded_native: TestEnum = Amf0Decoder::from_slice(&buf).deserialize().unwrap();
1023        let decoded_value_native: TestEnum = Deserialize::deserialize(decoded_value.clone()).unwrap();
1024        assert_eq!(original, decoded_native);
1025        assert_eq!(original, decoded_value_native);
1026        let mut buf2 = Vec::new();
1027        {
1028            let mut encoder = Amf0Encoder::new(&mut buf2);
1029            decoded_value.serialize(&mut encoder).unwrap();
1030        }
1031        assert_eq!(buf, buf2);
1032    }
1033
1034    #[derive(Serialize, Deserialize, PartialEq, Debug)]
1035    struct UnitStruct;
1036
1037    #[test]
1038    fn roundtrip_unit_struct() {
1039        let original = UnitStruct;
1040        let mut buf = Vec::new();
1041        {
1042            let mut encoder = Amf0Encoder::new(&mut buf);
1043            original.serialize(&mut encoder).unwrap();
1044        }
1045        let decoded_value = Amf0Decoder::from_slice(&buf).decode_value().unwrap();
1046        let decoded_native: UnitStruct = Amf0Decoder::from_slice(&buf).deserialize().unwrap();
1047        let decoded_value_native: UnitStruct = Deserialize::deserialize(decoded_value.clone()).unwrap();
1048        assert_eq!(&original, &decoded_native);
1049        assert_eq!(&original, &decoded_value_native);
1050        let mut buf2 = Vec::new();
1051        {
1052            let mut encoder = Amf0Encoder::new(&mut buf2);
1053            decoded_value.serialize(&mut encoder).unwrap();
1054        }
1055        assert_eq!(buf, buf2);
1056    }
1057
1058    #[test]
1059    fn roundtrip_enum_map() {
1060        let mut original: HashMap<String, TestEnum> = HashMap::new();
1061        original.insert("k1".to_string(), TestEnum::NewType(99));
1062        let mut buf = Vec::new();
1063        {
1064            let mut encoder = Amf0Encoder::new(&mut buf);
1065            original.serialize(&mut encoder).unwrap();
1066        }
1067        let decoded_value = Amf0Decoder::from_slice(&buf).decode_value().unwrap();
1068        let decoded_native: HashMap<String, TestEnum> = Amf0Decoder::from_slice(&buf).deserialize().unwrap();
1069        let decoded_value_native: HashMap<String, TestEnum> = Deserialize::deserialize(decoded_value.clone()).unwrap();
1070        assert_eq!(original, decoded_native);
1071        assert_eq!(original, decoded_value_native);
1072        let mut buf2 = Vec::new();
1073        {
1074            let mut encoder = Amf0Encoder::new(&mut buf2);
1075            decoded_value.serialize(&mut encoder).unwrap();
1076        }
1077        assert_eq!(buf, buf2);
1078    }
1079}