1use std::io;
4
5use scuffle_bytes_util::zero_copy::ZeroCopyReader;
6use serde::de::{EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess};
7
8use crate::decoder::{Amf0Decoder, ObjectHeader};
9use crate::{Amf0Error, Amf0Marker, Amf0Value};
10
11mod stream;
12
13pub use stream::*;
14
15pub fn from_buf<'de, T>(buf: impl bytes::Buf) -> crate::Result<T>
17where
18 T: serde::de::Deserialize<'de>,
19{
20 let mut de = Amf0Decoder::from_buf(buf);
21 let value = T::deserialize(&mut de)?;
22 Ok(value)
23}
24
25pub fn from_reader<'de, T>(reader: impl io::Read) -> crate::Result<T>
27where
28 T: serde::de::Deserialize<'de>,
29{
30 let mut de = Amf0Decoder::from_reader(reader);
31 let value = T::deserialize(&mut de)?;
32 Ok(value)
33}
34
35pub fn from_slice<'de, T>(bytes: &'de [u8]) -> crate::Result<T>
37where
38 T: serde::de::Deserialize<'de>,
39{
40 let mut de = Amf0Decoder::from_slice(bytes);
41 let value = T::deserialize(&mut de)?;
42 Ok(value)
43}
44
45macro_rules! impl_de_number {
46 ($deserializser_fn:ident, $visit_fn:ident) => {
47 fn $deserializser_fn<V>(self, visitor: V) -> Result<V::Value, Self::Error>
48 where
49 V: serde::de::Visitor<'de>,
50 {
51 if let Amf0Marker::Number = self.peek_marker()? {
52 let value = self.decode_number()?;
54 if let Some(value) = ::num_traits::cast(value) {
55 visitor.$visit_fn(value)
56 } else {
57 visitor.visit_f64(value)
58 }
59 } else {
60 self.deserialize_any(visitor)
61 }
62 }
63 };
64}
65
66impl<'de, R> serde::de::Deserializer<'de> for &mut Amf0Decoder<R>
67where
68 R: ZeroCopyReader<'de>,
69{
70 type Error = Amf0Error;
71
72 serde::forward_to_deserialize_any! {
73 tuple tuple_struct ignored_any identifier
74 str string seq map unit unit_struct bool
75 f64 struct
76 }
77
78 impl_de_number!(deserialize_i8, visit_i8);
79
80 impl_de_number!(deserialize_i16, visit_i16);
81
82 impl_de_number!(deserialize_i32, visit_i32);
83
84 impl_de_number!(deserialize_i64, visit_i64);
85
86 impl_de_number!(deserialize_u8, visit_u8);
87
88 impl_de_number!(deserialize_u16, visit_u16);
89
90 impl_de_number!(deserialize_u32, visit_u32);
91
92 impl_de_number!(deserialize_u64, visit_u64);
93
94 impl_de_number!(deserialize_f32, visit_f32);
95
96 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
97 where
98 V: serde::de::Visitor<'de>,
99 {
100 if let Amf0Marker::StrictArray = self.peek_marker()? {
101 let array = self.decode_strict_array()?;
102 match array
103 .iter()
104 .map(|a| match a {
105 Amf0Value::Number(n) => num_traits::cast(*n).ok_or(()),
106 _ => Err(()),
107 })
108 .collect::<Result<_, _>>()
109 {
110 Ok(buf) => visitor.visit_byte_buf(buf),
111 Err(()) => Amf0Value::Array(array).deserialize_any(visitor),
112 }
113 } else {
114 self.deserialize_any(visitor)
115 }
116 }
117
118 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
119 where
120 V: serde::de::Visitor<'de>,
121 {
122 self.deserialize_byte_buf(visitor)
123 }
124
125 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
126 where
127 V: serde::de::Visitor<'de>,
128 {
129 if let Amf0Marker::String | Amf0Marker::LongString | Amf0Marker::XmlDocument = self.peek_marker()? {
130 let value = self.decode_string()?;
131 value.into_deserializer().deserialize_any(visitor)
132 } else {
133 self.deserialize_any(visitor)
134 }
135 }
136
137 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
138 where
139 V: serde::de::Visitor<'de>,
140 {
141 let marker = self.peek_marker()?;
142
143 match marker {
144 Amf0Marker::Boolean => visitor.visit_bool(self.decode_boolean()?),
145 Amf0Marker::Number | Amf0Marker::Date => visitor.visit_f64(self.decode_number()?),
146 Amf0Marker::String | Amf0Marker::LongString | Amf0Marker::XmlDocument => {
147 self.decode_string()?.into_deserializer().deserialize_any(visitor)
148 }
149 Amf0Marker::Null | Amf0Marker::Undefined => {
150 self.decode_null()?;
151 visitor.visit_unit()
152 },
153 Amf0Marker::Object | Amf0Marker::TypedObject | Amf0Marker::EcmaArray => {
154 let header = self.decode_object_header()?;
155 match header {
156 ObjectHeader::Object | ObjectHeader::TypedObject { .. } => visitor.visit_map(Object { de: self }),
157 ObjectHeader::EcmaArray { size } => visitor.visit_map(EcmaArray {
158 de: self,
159 remaining: size as usize,
160 }),
161 }
162 }
163 Amf0Marker::StrictArray => {
164 let size = self.decode_strict_array_header()? as usize;
165
166 visitor.visit_seq(StrictArray {
167 de: self,
168 remaining: size,
169 })
170 }
171 _ => Err(Amf0Error::UnsupportedMarker(marker)),
172 }
173 }
174
175 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
176 where
177 V: serde::de::Visitor<'de>,
178 {
179 if let Amf0Marker::Null | Amf0Marker::Undefined = self.peek_marker()? {
180 self.decode_null()?;
181 visitor.visit_none()
182 } else {
183 visitor.visit_some(self)
184 }
185 }
186
187 fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value, Self::Error>
188 where
189 V: serde::de::Visitor<'de>,
190 {
191 if name == stream::MULTI_VALUE_NEW_TYPE {
192 visitor.visit_seq(MultiValueDe { de: self })
193 } else {
194 visitor.visit_newtype_struct(self)
195 }
196 }
197
198 fn deserialize_enum<V>(
199 self,
200 _name: &'static str,
201 _variants: &'static [&'static str],
202 visitor: V,
203 ) -> Result<V::Value, Self::Error>
204 where
205 V: serde::de::Visitor<'de>,
206 {
207 visitor.visit_enum(Enum { de: self })
208 }
209}
210
211struct StrictArray<'a, R> {
212 de: &'a mut Amf0Decoder<R>,
213 remaining: usize,
214}
215
216impl<'de, R> SeqAccess<'de> for StrictArray<'_, R>
217where
218 R: ZeroCopyReader<'de>,
219{
220 type Error = Amf0Error;
221
222 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
223 where
224 T: serde::de::DeserializeSeed<'de>,
225 {
226 if self.remaining == 0 {
227 return Ok(None);
228 }
229
230 self.remaining -= 1;
231 seed.deserialize(&mut *self.de).map(Some)
232 }
233
234 fn size_hint(&self) -> Option<usize> {
235 Some(self.remaining)
236 }
237}
238
239struct Object<'a, R> {
240 de: &'a mut Amf0Decoder<R>,
241}
242
243impl<'de, R> MapAccess<'de> for Object<'_, R>
244where
245 R: ZeroCopyReader<'de>,
246{
247 type Error = Amf0Error;
248
249 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
250 where
251 K: serde::de::DeserializeSeed<'de>,
252 {
253 let Some(key) = self.de.decode_object_key()? else {
254 return Ok(None);
256 };
257
258 let string_de = key.into_deserializer();
259 seed.deserialize(string_de).map(Some)
260 }
261
262 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
263 where
264 V: serde::de::DeserializeSeed<'de>,
265 {
266 seed.deserialize(&mut *self.de)
267 }
268}
269
270struct EcmaArray<'a, R> {
271 de: &'a mut Amf0Decoder<R>,
272 remaining: usize,
273}
274
275impl<'de, R> MapAccess<'de> for EcmaArray<'_, R>
276where
277 R: ZeroCopyReader<'de>,
278{
279 type Error = Amf0Error;
280
281 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
282 where
283 K: serde::de::DeserializeSeed<'de>,
284 {
285 if self.remaining == 0 {
286 if self.de.has_remaining()? && self.de.peek_marker()? == Amf0Marker::ObjectEnd {
288 self.de.next_marker = None; }
290
291 return Ok(None);
292 }
293
294 self.remaining -= 1;
295
296 let s = self.de.decode_normal_string()?;
298 let string_de = s.into_deserializer();
299 seed.deserialize(string_de).map(Some)
300 }
301
302 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
303 where
304 V: serde::de::DeserializeSeed<'de>,
305 {
306 seed.deserialize(&mut *self.de)
307 }
308
309 fn size_hint(&self) -> Option<usize> {
310 Some(self.remaining)
311 }
312}
313
314struct Enum<'a, R> {
315 de: &'a mut Amf0Decoder<R>,
316}
317
318impl<'de, R> EnumAccess<'de> for Enum<'_, R>
319where
320 R: ZeroCopyReader<'de>,
321{
322 type Error = Amf0Error;
323 type Variant = Self;
324
325 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
326 where
327 V: serde::de::DeserializeSeed<'de>,
328 {
329 let variant = self.de.decode_string()?;
330 let string_de = IntoDeserializer::<Self::Error>::into_deserializer(variant);
331 let value = seed.deserialize(string_de)?;
332
333 Ok((value, self))
334 }
335}
336
337impl<'de, R> VariantAccess<'de> for Enum<'_, R>
338where
339 R: ZeroCopyReader<'de>,
340{
341 type Error = Amf0Error;
342
343 fn unit_variant(self) -> Result<(), Self::Error> {
344 Ok(())
345 }
346
347 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
348 where
349 T: serde::de::DeserializeSeed<'de>,
350 {
351 seed.deserialize(&mut *self.de)
352 }
353
354 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
355 where
356 V: serde::de::Visitor<'de>,
357 {
358 serde::de::Deserializer::deserialize_seq(self.de, visitor)
359 }
360
361 fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value, Self::Error>
362 where
363 V: serde::de::Visitor<'de>,
364 {
365 serde::de::Deserializer::deserialize_map(self.de, visitor)
366 }
367}
368
369#[cfg(test)]
370#[cfg_attr(all(test, coverage_nightly), coverage(off))]
371mod tests {
372 use core::f64;
373 use std::collections::HashMap;
374 use std::fmt::Debug;
375
376 use bytes::Bytes;
377 use scuffle_bytes_util::StringCow;
378 use serde_derive::Deserialize;
379
380 use crate::de::MultiValue;
381 use crate::decoder::Amf0Decoder;
382 use crate::{Amf0Error, Amf0Marker, Amf0Object, Amf0Value, from_buf};
383
384 #[test]
385 fn string() {
386 #[rustfmt::skip]
387 let bytes = [
388 Amf0Marker::String as u8,
389 0, 5, b'h', b'e', b'l', b'l', b'o',
391 ];
392
393 let value: String = from_buf(Bytes::from_owner(bytes)).unwrap();
394 assert_eq!(value, "hello");
395
396 #[rustfmt::skip]
397 let bytes = [
398 Amf0Marker::LongString as u8,
399 0, 0, 0, 5, b'h', b'e', b'l', b'l', b'o',
401 ];
402
403 let value: String = from_buf(Bytes::from_owner(bytes)).unwrap();
404 assert_eq!(value, "hello");
405
406 let bytes = [Amf0Marker::Boolean as u8, 0];
407 let err = from_buf::<String>(Bytes::from_owner(bytes)).unwrap_err();
408 assert_eq!(err.to_string(), "invalid type: boolean `false`, expected a string");
409 }
410
411 #[test]
412 fn bool() {
413 let bytes = [Amf0Marker::Boolean as u8, 1];
414 let value: bool = from_buf(Bytes::from_owner(bytes)).unwrap();
415 assert!(value);
416 }
417
418 fn number_test<'de, T>(one: T)
419 where
420 T: serde::Deserialize<'de> + PartialEq + Debug,
421 {
422 const NUMBER_ONE: [u8; 9] = const {
423 let one = 1.0f64.to_be_bytes();
424 [
425 Amf0Marker::Number as u8,
426 one[0],
427 one[1],
428 one[2],
429 one[3],
430 one[4],
431 one[5],
432 one[6],
433 one[7],
434 ]
435 };
436
437 let value: T = from_buf(Bytes::from_static(&NUMBER_ONE)).unwrap();
438 assert_eq!(value, one);
439 }
440
441 #[test]
442 fn numbers() {
443 number_test(1f64);
444 number_test(1u8);
445 number_test(1u16);
446 number_test(1u32);
447 number_test(1u64);
448 number_test(1i8);
449 number_test(1i16);
450 number_test(1i32);
451 number_test(1i64);
452 number_test(1f32);
453
454 let mut bytes = vec![Amf0Marker::Date as u8];
455 bytes.extend_from_slice(&f64::consts::PI.to_be_bytes());
456 bytes.extend_from_slice(&0u16.to_be_bytes()); let value: f64 = from_buf(Bytes::from_owner(bytes)).unwrap();
458 assert_eq!(value, f64::consts::PI);
459 }
460
461 #[test]
462 fn char() {
463 let err = from_buf::<char>(Bytes::from_owner([])).unwrap_err();
464
465 assert!(matches!(
466 err,
467 Amf0Error::Io(ref io_err) if io_err.kind() == std::io::ErrorKind::UnexpectedEof && io_err.to_string().contains("failed to fill whole buffer")
468 ));
469 }
470
471 #[test]
472 fn optional() {
473 let bytes = [Amf0Marker::Null as u8];
474 let value: Option<bool> = from_buf(Bytes::from_owner(bytes)).unwrap();
475 assert_eq!(value, None);
476
477 let bytes = [Amf0Marker::Null as u8];
478 from_buf::<()>(Bytes::from_owner(bytes)).unwrap();
479
480 let bytes = [Amf0Marker::Undefined as u8];
481 let value: Option<bool> = from_buf(Bytes::from_owner(bytes)).unwrap();
482 assert_eq!(value, None);
483
484 let bytes = [Amf0Marker::Boolean as u8, 0];
485 let value: Option<bool> = from_buf(Bytes::from_owner(bytes)).unwrap();
486 assert_eq!(value, Some(false));
487
488 #[derive(Deserialize, PartialEq, Debug)]
489 struct Unit;
490
491 let bytes = [Amf0Marker::Null as u8];
492 let value: Unit = from_buf(Bytes::from_owner(bytes)).unwrap();
493 assert_eq!(value, Unit);
494 }
495
496 #[test]
497 fn newtype_struct() {
498 #[derive(Deserialize, Debug, PartialEq)]
499 struct Test(String);
500
501 #[rustfmt::skip]
502 let bytes = [
503 Amf0Marker::String as u8,
504 0, 5, b'h', b'e', b'l', b'l', b'o',
506 ];
507 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
508 assert_eq!(value, Test("hello".to_string()));
509 }
510
511 #[test]
512 fn tuple_struct() {
513 #[derive(Deserialize, Debug, PartialEq)]
514 struct Test(bool, String);
515
516 #[rustfmt::skip]
517 let bytes = [
518 Amf0Marker::StrictArray as u8,
519 0, 0, 0, 2, Amf0Marker::Boolean as u8,
521 1,
522 Amf0Marker::String as u8,
523 0, 5, b'h', b'e', b'l', b'l', b'o',
525 ];
526 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
527 assert_eq!(value, Test(true, "hello".to_string()));
528
529 #[rustfmt::skip]
530 let bytes = [
531 Amf0Marker::StrictArray as u8,
532 0, 0, 0, 1, Amf0Marker::Boolean as u8,
534 1,
535 ];
536 let err = from_buf::<Test>(Bytes::from_owner(bytes)).unwrap_err();
537 assert_eq!(
538 err.to_string(),
539 "invalid length 1, expected tuple struct Test with 2 elements"
540 );
541 }
542
543 #[test]
544 fn typed_object() {
545 #[derive(Deserialize, Debug, PartialEq)]
546 struct Test {
547 a: bool,
548 b: String,
549 }
550
551 #[rustfmt::skip]
552 let bytes = [
553 Amf0Marker::TypedObject as u8,
554 0, 1, b'a', 0, 1, b'a', Amf0Marker::Boolean as u8,
559 1,
560 0, 1, b'b', Amf0Marker::String as u8,
563 0, 5, b'h', b'e', b'l', b'l', b'o',
565 0, 0, Amf0Marker::ObjectEnd as u8,
566 ];
567 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
568 assert_eq!(
569 value,
570 Test {
571 a: true,
572 b: "hello".to_string()
573 }
574 );
575 }
576
577 #[test]
578 fn simple_struct() {
579 #[derive(Deserialize, Debug, PartialEq)]
580 struct Test {
581 a: bool,
582 b: String,
583 c: f64,
584 }
585
586 #[rustfmt::skip]
587 let mut bytes = vec![
588 Amf0Marker::Object as u8,
589 0, 1, b'a', Amf0Marker::Boolean as u8, 1,
593 0, 1, b'b', Amf0Marker::String as u8, 0, 1, b'b', 0, 1, b'c', Amf0Marker::Number as u8, ];
602 bytes.extend_from_slice(&f64::consts::PI.to_be_bytes());
603 bytes.extend_from_slice(&[0, 0, Amf0Marker::ObjectEnd as u8]);
604 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
605
606 assert_eq!(
607 value,
608 Test {
609 a: true,
610 b: "b".to_string(),
611 c: f64::consts::PI,
612 }
613 );
614
615 #[rustfmt::skip]
616 let mut bytes = vec![
617 Amf0Marker::EcmaArray as u8,
618 0, 0, 0, 3, 0, 1, b'a', Amf0Marker::Boolean as u8, 1,
623 0, 1, b'b', Amf0Marker::String as u8, 0, 1, b'b', 0, 1, b'c', Amf0Marker::Number as u8, ];
632 bytes.extend_from_slice(&f64::consts::PI.to_be_bytes());
633 bytes.extend_from_slice(&[0, 0, 0]); let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
635
636 assert_eq!(
637 value,
638 Test {
639 a: true,
640 b: "b".to_string(),
641 c: f64::consts::PI,
642 }
643 );
644
645 let err = from_buf::<Test>(Bytes::from_owner([Amf0Marker::String as u8, 0, 0])).unwrap_err();
646 assert_eq!(err.to_string(), "invalid type: string \"\", expected struct Test");
647 }
648
649 #[test]
650 fn simple_enum() {
651 #[derive(Deserialize, Debug, PartialEq)]
652 enum Test {
653 A,
654 B,
655 }
656
657 #[rustfmt::skip]
658 let bytes = vec![
659 Amf0Marker::String as u8,
660 0, 1, b'A',
662 ];
663 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
664 assert_eq!(value, Test::A);
665
666 #[rustfmt::skip]
667 let bytes = vec![
668 Amf0Marker::String as u8,
669 0, 1, b'B',
671 ];
672 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
673 assert_eq!(value, Test::B);
674 }
675
676 #[test]
677 fn complex_enum() {
678 #[derive(Deserialize, Debug, PartialEq)]
679 enum Test {
680 A(bool),
681 B {
682 a: String,
683 b: String,
684 },
685 C(bool, String),
686 }
687
688 #[rustfmt::skip]
689 let bytes = [
690 Amf0Marker::String as u8,
691 0, 1, b'A',
693 Amf0Marker::Boolean as u8,
694 1,
695 ];
696 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
697 assert_eq!(value, Test::A(true));
698
699 #[rustfmt::skip]
700 let bytes = [
701 Amf0Marker::String as u8,
702 0, 1, b'B',
704 Amf0Marker::Object as u8,
705 0, 1, b'a',
707 Amf0Marker::String as u8,
708 0, 5, b'h', b'e', b'l', b'l', b'o',
710 0, 1, b'b',
712 Amf0Marker::String as u8,
713 0, 5, b'w', b'o', b'r', b'l', b'd',
715 0, 0, Amf0Marker::ObjectEnd as u8,
716 ];
717 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
718 assert_eq!(
719 value,
720 Test::B {
721 a: "hello".to_string(),
722 b: "world".to_string()
723 }
724 );
725
726 #[rustfmt::skip]
727 let bytes = [
728 Amf0Marker::String as u8,
729 0, 1, b'C',
731 Amf0Marker::StrictArray as u8,
732 0, 0, 0, 2, Amf0Marker::Boolean as u8,
734 1,
735 Amf0Marker::String as u8,
736 0, 5, b'h', b'e', b'l', b'l', b'o',
738 ];
739 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
740 assert_eq!(value, Test::C(true, "hello".to_string()));
741 }
742
743 #[test]
744 fn series() {
745 #[rustfmt::skip]
746 let mut bytes = vec![
747 Amf0Marker::String as u8,
748 0, 5, b'h', b'e', b'l', b'l', b'o',
750 Amf0Marker::Boolean as u8,
751 1,
752 Amf0Marker::Number as u8,
753 ];
754 bytes.extend_from_slice(&f64::consts::PI.to_be_bytes());
755
756 let mut de = Amf0Decoder::from_buf(Bytes::from_owner(bytes));
757 let value: String = serde::de::Deserialize::deserialize(&mut de).unwrap();
758 assert_eq!(value, "hello");
759 let value: bool = serde::de::Deserialize::deserialize(&mut de).unwrap();
760 assert!(value);
761 let value: f64 = serde::de::Deserialize::deserialize(&mut de).unwrap();
762 assert_eq!(value, f64::consts::PI);
763 }
764
765 #[test]
766 fn flatten() {
767 #[rustfmt::skip]
768 let bytes = [
769 Amf0Marker::Object as u8,
770 0, 1, b'a',
772 Amf0Marker::Boolean as u8,
773 1,
774 0, 1, b'b',
776 Amf0Marker::String as u8,
777 0, 1, b'b',
779 0, 1, b'c',
781 Amf0Marker::String as u8,
782 0, 1, b'c',
784 0, 0, Amf0Marker::ObjectEnd as u8,
785 ];
786
787 #[derive(Deserialize, Debug, PartialEq)]
788 struct Test<'a> {
789 b: String,
790 #[serde(flatten, borrow)]
791 other: HashMap<StringCow<'a>, Amf0Value<'a>>,
792 }
793
794 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
795 assert_eq!(
796 value,
797 Test {
798 b: "b".to_string(),
799 other: vec![
800 ("a".into(), Amf0Value::from(true)),
801 ("c".into(), StringCow::from_static("c").into())
802 ]
803 .into_iter()
804 .collect(),
805 }
806 );
807 }
808
809 #[test]
810 fn all() {
811 let bytes = [
812 Amf0Marker::String as u8,
813 0,
814 5, b'h',
816 b'e',
817 b'l',
818 b'l',
819 b'o',
820 Amf0Marker::Boolean as u8,
821 1,
822 Amf0Marker::Object as u8,
823 0,
824 1, b'a',
826 Amf0Marker::Boolean as u8,
827 1,
828 0,
829 0,
830 Amf0Marker::ObjectEnd as u8,
831 ];
832
833 let mut de = Amf0Decoder::from_buf(Bytes::from_owner(bytes));
834 let values = de.decode_all().unwrap();
835 assert_eq!(
836 values,
837 vec![
838 Amf0Value::String("hello".into()),
839 Amf0Value::Boolean(true),
840 Amf0Value::Object([("a".into(), Amf0Value::Boolean(true))].into_iter().collect())
841 ]
842 );
843 }
844
845 #[test]
846 fn multi_value() {
847 #[rustfmt::skip]
848 let bytes = [
849 Amf0Marker::String as u8,
850 0, 5, b'h', b'e', b'l', b'l', b'o',
852 Amf0Marker::Boolean as u8,
853 1,
854 Amf0Marker::Object as u8,
855 0, 1, b'a',
857 Amf0Marker::Boolean as u8,
858 1,
859 0, 0, Amf0Marker::ObjectEnd as u8,
860 ];
861
862 let mut de = Amf0Decoder::from_buf(Bytes::from_owner(bytes));
863 let values: MultiValue<(String, bool, Amf0Object)> = de.deserialize().unwrap();
865 assert_eq!(values.0.0, "hello");
866 assert!(values.0.1);
867 assert_eq!(
868 values.0.2,
869 [("a".into(), Amf0Value::Boolean(true))].into_iter().collect::<Amf0Object>()
870 );
871 }
872
873 #[test]
874 fn deserializer_stream() {
875 #[rustfmt::skip]
876 let bytes = [
877 Amf0Marker::String as u8,
878 0, 5, b'h', b'e', b'l', b'l', b'o',
880 Amf0Marker::String as u8,
881 0, 5, b'w', b'o', b'r', b'l', b'd',
883 Amf0Marker::String as u8,
884 0, 1, b'a',
886 ];
887
888 let mut de = Amf0Decoder::from_buf(Bytes::from_owner(bytes));
889 let mut stream = de.deserialize_stream::<String>();
890 assert_eq!(stream.next().unwrap().unwrap(), "hello");
891 assert_eq!(stream.next().unwrap().unwrap(), "world");
892 assert_eq!(stream.next().unwrap().unwrap(), "a");
893 assert_eq!(stream.next().transpose().unwrap(), None);
894 }
895}