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};
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
45impl<'de, R> serde::de::Deserializer<'de> for &mut Amf0Decoder<R>
46where
47 R: ZeroCopyReader<'de>,
48{
49 type Error = Amf0Error;
50
51 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
52 where
53 V: serde::de::Visitor<'de>,
54 {
55 let marker = self.peek_marker()?;
56
57 match marker {
58 Amf0Marker::Boolean => self.deserialize_bool(visitor),
59 Amf0Marker::Number | Amf0Marker::Date => self.deserialize_f64(visitor),
60 Amf0Marker::String | Amf0Marker::LongString | Amf0Marker::XmlDocument => self.deserialize_str(visitor),
61 Amf0Marker::Null | Amf0Marker::Undefined => self.deserialize_unit(visitor),
62 Amf0Marker::Object | Amf0Marker::TypedObject | Amf0Marker::EcmaArray => self.deserialize_map(visitor),
63 Amf0Marker::StrictArray => self.deserialize_seq(visitor),
64 _ => Err(Amf0Error::UnsupportedMarker(marker)),
65 }
66 }
67
68 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
69 where
70 V: serde::de::Visitor<'de>,
71 {
72 let value = self.decode_boolean()?;
73 visitor.visit_bool(value)
74 }
75
76 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
77 where
78 V: serde::de::Visitor<'de>,
79 {
80 self.deserialize_i64(visitor)
81 }
82
83 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
84 where
85 V: serde::de::Visitor<'de>,
86 {
87 self.deserialize_i64(visitor)
88 }
89
90 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
91 where
92 V: serde::de::Visitor<'de>,
93 {
94 self.deserialize_i64(visitor)
95 }
96
97 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
98 where
99 V: serde::de::Visitor<'de>,
100 {
101 let value = self.decode_number()?;
102 visitor.visit_i64(value as i64)
103 }
104
105 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
106 where
107 V: serde::de::Visitor<'de>,
108 {
109 self.deserialize_u64(visitor)
110 }
111
112 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
113 where
114 V: serde::de::Visitor<'de>,
115 {
116 self.deserialize_u64(visitor)
117 }
118
119 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
120 where
121 V: serde::de::Visitor<'de>,
122 {
123 self.deserialize_u64(visitor)
124 }
125
126 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
127 where
128 V: serde::de::Visitor<'de>,
129 {
130 let value = self.decode_number()?;
131 visitor.visit_u64(value as u64)
132 }
133
134 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
135 where
136 V: serde::de::Visitor<'de>,
137 {
138 self.deserialize_f64(visitor)
139 }
140
141 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
142 where
143 V: serde::de::Visitor<'de>,
144 {
145 let value = self.decode_number()?;
146 visitor.visit_f64(value)
147 }
148
149 fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
150 where
151 V: serde::de::Visitor<'de>,
152 {
153 Err(Amf0Error::CharNotSupported)
154 }
155
156 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
157 where
158 V: serde::de::Visitor<'de>,
159 {
160 let value = self.decode_string()?;
161 value.into_deserializer().deserialize_string(visitor)
162 }
163
164 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
165 where
166 V: serde::de::Visitor<'de>,
167 {
168 let value = self.decode_string()?;
169 value.into_deserializer().deserialize_str(visitor)
170 }
171
172 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
173 where
174 V: serde::de::Visitor<'de>,
175 {
176 self.deserialize_seq(visitor)
177 }
178
179 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
180 where
181 V: serde::de::Visitor<'de>,
182 {
183 self.deserialize_seq(visitor)
184 }
185
186 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
187 where
188 V: serde::de::Visitor<'de>,
189 {
190 let marker = self.peek_marker()?;
191
192 if marker == Amf0Marker::Null || marker == Amf0Marker::Undefined {
193 self.next_marker = None; visitor.visit_none()
196 } else {
197 visitor.visit_some(self)
198 }
199 }
200
201 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
202 where
203 V: serde::de::Visitor<'de>,
204 {
205 self.decode_null()?;
206 visitor.visit_unit()
207 }
208
209 fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value, Self::Error>
210 where
211 V: serde::de::Visitor<'de>,
212 {
213 self.deserialize_unit(visitor)
214 }
215
216 fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value, Self::Error>
217 where
218 V: serde::de::Visitor<'de>,
219 {
220 if name == stream::MULTI_VALUE_NEW_TYPE {
221 visitor.visit_seq(MultiValueDe { de: self })
222 } else {
223 visitor.visit_newtype_struct(self)
224 }
225 }
226
227 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
228 where
229 V: serde::de::Visitor<'de>,
230 {
231 let size = self.decode_strict_array_header()? as usize;
232
233 visitor.visit_seq(StrictArray {
234 de: self,
235 remaining: size,
236 })
237 }
238
239 fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
240 where
241 V: serde::de::Visitor<'de>,
242 {
243 let size = self.decode_strict_array_header()? as usize;
244
245 if len != size {
246 return Err(Amf0Error::WrongArrayLength {
247 expected: len,
248 got: size,
249 });
250 }
251
252 visitor.visit_seq(StrictArray {
253 de: self,
254 remaining: size,
255 })
256 }
257
258 fn deserialize_tuple_struct<V>(self, _name: &'static str, len: usize, visitor: V) -> Result<V::Value, Self::Error>
259 where
260 V: serde::de::Visitor<'de>,
261 {
262 self.deserialize_tuple(len, visitor)
263 }
264
265 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
266 where
267 V: serde::de::Visitor<'de>,
268 {
269 let header = self.decode_object_header()?;
270
271 match header {
272 ObjectHeader::Object | ObjectHeader::TypedObject { .. } => visitor.visit_map(Object { de: self }),
273 ObjectHeader::EcmaArray { size } => visitor.visit_map(EcmaArray {
274 de: self,
275 remaining: size as usize,
276 }),
277 }
278 }
279
280 fn deserialize_struct<V>(
281 self,
282 _name: &'static str,
283 _fields: &'static [&'static str],
284 visitor: V,
285 ) -> Result<V::Value, Self::Error>
286 where
287 V: serde::de::Visitor<'de>,
288 {
289 self.deserialize_map(visitor)
290 }
291
292 fn deserialize_enum<V>(
293 self,
294 _name: &'static str,
295 _variants: &'static [&'static str],
296 visitor: V,
297 ) -> Result<V::Value, Self::Error>
298 where
299 V: serde::de::Visitor<'de>,
300 {
301 visitor.visit_enum(Enum { de: self })
302 }
303
304 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
305 where
306 V: serde::de::Visitor<'de>,
307 {
308 let s = self.decode_string()?;
309 s.into_deserializer().deserialize_identifier(visitor)
310 }
311
312 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
313 where
314 V: serde::de::Visitor<'de>,
315 {
316 self.deserialize_any(visitor)
317 }
318}
319
320struct StrictArray<'a, R> {
321 de: &'a mut Amf0Decoder<R>,
322 remaining: usize,
323}
324
325impl<'de, R> SeqAccess<'de> for StrictArray<'_, R>
326where
327 R: ZeroCopyReader<'de>,
328{
329 type Error = Amf0Error;
330
331 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
332 where
333 T: serde::de::DeserializeSeed<'de>,
334 {
335 if self.remaining == 0 {
336 return Ok(None);
337 }
338
339 self.remaining -= 1;
340 seed.deserialize(&mut *self.de).map(Some)
341 }
342
343 fn size_hint(&self) -> Option<usize> {
344 Some(self.remaining)
345 }
346}
347
348struct Object<'a, R> {
349 de: &'a mut Amf0Decoder<R>,
350}
351
352impl<'de, R> MapAccess<'de> for Object<'_, R>
353where
354 R: ZeroCopyReader<'de>,
355{
356 type Error = Amf0Error;
357
358 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
359 where
360 K: serde::de::DeserializeSeed<'de>,
361 {
362 let Some(key) = self.de.decode_object_key()? else {
363 return Ok(None);
365 };
366
367 let string_de = key.into_deserializer();
368 seed.deserialize(string_de).map(Some)
369 }
370
371 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
372 where
373 V: serde::de::DeserializeSeed<'de>,
374 {
375 seed.deserialize(&mut *self.de)
376 }
377}
378
379struct EcmaArray<'a, R> {
380 de: &'a mut Amf0Decoder<R>,
381 remaining: usize,
382}
383
384impl<'de, R> MapAccess<'de> for EcmaArray<'_, R>
385where
386 R: ZeroCopyReader<'de>,
387{
388 type Error = Amf0Error;
389
390 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
391 where
392 K: serde::de::DeserializeSeed<'de>,
393 {
394 if self.remaining == 0 {
395 if self.de.has_remaining()? && self.de.peek_marker()? == Amf0Marker::ObjectEnd {
397 self.de.next_marker = None; }
399
400 return Ok(None);
401 }
402
403 self.remaining -= 1;
404
405 let s = self.de.decode_normal_string()?;
407 let string_de = s.into_deserializer();
408 seed.deserialize(string_de).map(Some)
409 }
410
411 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
412 where
413 V: serde::de::DeserializeSeed<'de>,
414 {
415 seed.deserialize(&mut *self.de)
416 }
417
418 fn size_hint(&self) -> Option<usize> {
419 Some(self.remaining)
420 }
421}
422
423struct Enum<'a, R> {
424 de: &'a mut Amf0Decoder<R>,
425}
426
427impl<'de, R> EnumAccess<'de> for Enum<'_, R>
428where
429 R: ZeroCopyReader<'de>,
430{
431 type Error = Amf0Error;
432 type Variant = Self;
433
434 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
435 where
436 V: serde::de::DeserializeSeed<'de>,
437 {
438 let variant = self.de.decode_string()?;
439 let string_de = IntoDeserializer::<Self::Error>::into_deserializer(variant);
440 let value = seed.deserialize(string_de)?;
441
442 Ok((value, self))
443 }
444}
445
446impl<'de, R> VariantAccess<'de> for Enum<'_, R>
447where
448 R: ZeroCopyReader<'de>,
449{
450 type Error = Amf0Error;
451
452 fn unit_variant(self) -> Result<(), Self::Error> {
453 Ok(())
454 }
455
456 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
457 where
458 T: serde::de::DeserializeSeed<'de>,
459 {
460 seed.deserialize(&mut *self.de)
461 }
462
463 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
464 where
465 V: serde::de::Visitor<'de>,
466 {
467 serde::de::Deserializer::deserialize_seq(self.de, visitor)
468 }
469
470 fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value, Self::Error>
471 where
472 V: serde::de::Visitor<'de>,
473 {
474 serde::de::Deserializer::deserialize_map(self.de, visitor)
475 }
476}
477
478#[cfg(test)]
479#[cfg_attr(all(test, coverage_nightly), coverage(off))]
480mod tests {
481 use core::f64;
482 use std::collections::HashMap;
483 use std::fmt::Debug;
484
485 use bytes::Bytes;
486 use scuffle_bytes_util::StringCow;
487 use serde_derive::Deserialize;
488
489 use crate::de::MultiValue;
490 use crate::decoder::Amf0Decoder;
491 use crate::{Amf0Error, Amf0Marker, Amf0Object, Amf0Value, from_buf};
492
493 #[test]
494 fn string() {
495 #[rustfmt::skip]
496 let bytes = [
497 Amf0Marker::String as u8,
498 0, 5, b'h', b'e', b'l', b'l', b'o',
500 ];
501
502 let value: String = from_buf(Bytes::from_owner(bytes)).unwrap();
503 assert_eq!(value, "hello");
504
505 #[rustfmt::skip]
506 let bytes = [
507 Amf0Marker::LongString as u8,
508 0, 0, 0, 5, b'h', b'e', b'l', b'l', b'o',
510 ];
511
512 let value: String = from_buf(Bytes::from_owner(bytes)).unwrap();
513 assert_eq!(value, "hello");
514
515 let bytes = [Amf0Marker::Boolean as u8];
516 let err = from_buf::<String>(Bytes::from_owner(bytes)).unwrap_err();
517 assert!(matches!(
518 err,
519 Amf0Error::UnexpectedType {
520 expected: [Amf0Marker::String, Amf0Marker::LongString, Amf0Marker::XmlDocument],
521 got: Amf0Marker::Boolean
522 }
523 ));
524 }
525
526 #[test]
527 fn bool() {
528 let bytes = [Amf0Marker::Boolean as u8, 1];
529 let value: bool = from_buf(Bytes::from_owner(bytes)).unwrap();
530 assert!(value);
531
532 let bytes = [Amf0Marker::String as u8];
533 let err = from_buf::<bool>(Bytes::from_owner(bytes)).unwrap_err();
534 assert!(matches!(
535 err,
536 Amf0Error::UnexpectedType {
537 expected: [Amf0Marker::Boolean],
538 got: Amf0Marker::String
539 }
540 ));
541 }
542
543 fn number_test<'de, T>(one: T)
544 where
545 T: serde::Deserialize<'de> + PartialEq + Debug,
546 {
547 const NUMBER_ONE: [u8; 9] = const {
548 let one = 1.0f64.to_be_bytes();
549 [
550 Amf0Marker::Number as u8,
551 one[0],
552 one[1],
553 one[2],
554 one[3],
555 one[4],
556 one[5],
557 one[6],
558 one[7],
559 ]
560 };
561
562 let value: T = from_buf(Bytes::from_static(&NUMBER_ONE)).unwrap();
563 assert_eq!(value, one);
564 }
565
566 #[test]
567 fn numbers() {
568 number_test(1u8);
569 number_test(1u16);
570 number_test(1u32);
571 number_test(1u64);
572 number_test(1i8);
573 number_test(1i16);
574 number_test(1i32);
575 number_test(1i64);
576 number_test(1f32);
577 number_test(1f64);
578
579 let mut bytes = vec![Amf0Marker::Date as u8];
580 bytes.extend_from_slice(&f64::consts::PI.to_be_bytes());
581 bytes.extend_from_slice(&0u16.to_be_bytes()); let value: f64 = from_buf(Bytes::from_owner(bytes)).unwrap();
583 assert_eq!(value, f64::consts::PI);
584
585 let bytes = [Amf0Marker::Boolean as u8];
586 let err = from_buf::<f64>(Bytes::from_owner(bytes)).unwrap_err();
587 assert!(matches!(
588 err,
589 Amf0Error::UnexpectedType {
590 expected: [Amf0Marker::Number, Amf0Marker::Date],
591 got: Amf0Marker::Boolean
592 }
593 ));
594 }
595
596 #[test]
597 fn char() {
598 let err = from_buf::<char>(Bytes::from_owner([])).unwrap_err();
599 assert!(matches!(err, Amf0Error::CharNotSupported));
600 }
601
602 #[test]
603 fn optional() {
604 let bytes = [Amf0Marker::Null as u8];
605 let value: Option<bool> = from_buf(Bytes::from_owner(bytes)).unwrap();
606 assert_eq!(value, None);
607
608 let bytes = [Amf0Marker::Null as u8];
609 from_buf::<()>(Bytes::from_owner(bytes)).unwrap();
610
611 let bytes = [Amf0Marker::String as u8];
612 let err = from_buf::<()>(Bytes::from_owner(bytes)).unwrap_err();
613 assert!(matches!(
614 err,
615 Amf0Error::UnexpectedType {
616 expected: [Amf0Marker::Null, Amf0Marker::Undefined],
617 got: Amf0Marker::String
618 }
619 ));
620
621 let bytes = [Amf0Marker::Undefined as u8];
622 let value: Option<bool> = from_buf(Bytes::from_owner(bytes)).unwrap();
623 assert_eq!(value, None);
624
625 let bytes = [Amf0Marker::Boolean as u8, 0];
626 let value: Option<bool> = from_buf(Bytes::from_owner(bytes)).unwrap();
627 assert_eq!(value, Some(false));
628
629 #[derive(Deserialize, PartialEq, Debug)]
630 struct Unit;
631
632 let bytes = [Amf0Marker::Null as u8];
633 let value: Unit = from_buf(Bytes::from_owner(bytes)).unwrap();
634 assert_eq!(value, Unit);
635 }
636
637 #[test]
638 fn newtype_struct() {
639 #[derive(Deserialize, Debug, PartialEq)]
640 struct Test(String);
641
642 #[rustfmt::skip]
643 let bytes = [
644 Amf0Marker::String as u8,
645 0, 5, b'h', b'e', b'l', b'l', b'o',
647 ];
648 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
649 assert_eq!(value, Test("hello".to_string()));
650 }
651
652 #[test]
653 fn tuple_struct() {
654 #[derive(Deserialize, Debug, PartialEq)]
655 struct Test(bool, String);
656
657 #[rustfmt::skip]
658 let bytes = [
659 Amf0Marker::StrictArray as u8,
660 0, 0, 0, 2, Amf0Marker::Boolean as u8,
662 1,
663 Amf0Marker::String as u8,
664 0, 5, b'h', b'e', b'l', b'l', b'o',
666 ];
667 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
668 assert_eq!(value, Test(true, "hello".to_string()));
669
670 #[rustfmt::skip]
671 let bytes = [
672 Amf0Marker::StrictArray as u8,
673 0, 0, 0, 1, Amf0Marker::Boolean as u8,
675 1,
676 ];
677 let err = from_buf::<Test>(Bytes::from_owner(bytes)).unwrap_err();
678 assert!(matches!(err, Amf0Error::WrongArrayLength { expected: 2, got: 1 }));
679 }
680
681 #[test]
682 fn typed_object() {
683 #[derive(Deserialize, Debug, PartialEq)]
684 struct Test {
685 a: bool,
686 b: String,
687 }
688
689 #[rustfmt::skip]
690 let bytes = [
691 Amf0Marker::TypedObject as u8,
692 0, 1, b'a', 0, 1, b'a', Amf0Marker::Boolean as u8,
697 1,
698 0, 1, b'b', Amf0Marker::String as u8,
701 0, 5, b'h', b'e', b'l', b'l', b'o',
703 0, 0, Amf0Marker::ObjectEnd as u8,
704 ];
705 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
706 assert_eq!(
707 value,
708 Test {
709 a: true,
710 b: "hello".to_string()
711 }
712 );
713 }
714
715 #[test]
716 fn simple_struct() {
717 #[derive(Deserialize, Debug, PartialEq)]
718 struct Test {
719 a: bool,
720 b: String,
721 c: f64,
722 }
723
724 #[rustfmt::skip]
725 let mut bytes = vec![
726 Amf0Marker::Object as u8,
727 0, 1, b'a', Amf0Marker::Boolean as u8, 1,
731 0, 1, b'b', Amf0Marker::String as u8, 0, 1, b'b', 0, 1, b'c', Amf0Marker::Number as u8, ];
740 bytes.extend_from_slice(&f64::consts::PI.to_be_bytes());
741 bytes.extend_from_slice(&[0, 0, Amf0Marker::ObjectEnd as u8]);
742 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
743
744 assert_eq!(
745 value,
746 Test {
747 a: true,
748 b: "b".to_string(),
749 c: f64::consts::PI,
750 }
751 );
752
753 #[rustfmt::skip]
754 let mut bytes = vec![
755 Amf0Marker::EcmaArray as u8,
756 0, 0, 0, 3, 0, 1, b'a', Amf0Marker::Boolean as u8, 1,
761 0, 1, b'b', Amf0Marker::String as u8, 0, 1, b'b', 0, 1, b'c', Amf0Marker::Number as u8, ];
770 bytes.extend_from_slice(&f64::consts::PI.to_be_bytes());
771 bytes.extend_from_slice(&[0, 0, 0]); let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
773
774 assert_eq!(
775 value,
776 Test {
777 a: true,
778 b: "b".to_string(),
779 c: f64::consts::PI,
780 }
781 );
782
783 let err = from_buf::<Test>(Bytes::from_owner([Amf0Marker::String as u8])).unwrap_err();
784 assert!(matches!(
785 err,
786 Amf0Error::UnexpectedType {
787 expected: [Amf0Marker::Object, Amf0Marker::TypedObject, Amf0Marker::EcmaArray],
788 got: Amf0Marker::String
789 }
790 ));
791 }
792
793 #[test]
794 fn simple_enum() {
795 #[derive(Deserialize, Debug, PartialEq)]
796 enum Test {
797 A,
798 B,
799 }
800
801 #[rustfmt::skip]
802 let bytes = vec![
803 Amf0Marker::String as u8,
804 0, 1, b'A',
806 ];
807 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
808 assert_eq!(value, Test::A);
809
810 #[rustfmt::skip]
811 let bytes = vec![
812 Amf0Marker::String as u8,
813 0, 1, b'B',
815 ];
816 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
817 assert_eq!(value, Test::B);
818 }
819
820 #[test]
821 fn complex_enum() {
822 #[derive(Deserialize, Debug, PartialEq)]
823 enum Test {
824 A(bool),
825 B { a: String, b: String },
826 C(bool, String),
827 }
828
829 #[rustfmt::skip]
830 let bytes = [
831 Amf0Marker::String as u8,
832 0, 1, b'A',
834 Amf0Marker::Boolean as u8,
835 1,
836 ];
837 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
838 assert_eq!(value, Test::A(true));
839
840 #[rustfmt::skip]
841 let bytes = [
842 Amf0Marker::String as u8,
843 0, 1, b'B',
845 Amf0Marker::Object as u8,
846 0, 1, b'a',
848 Amf0Marker::String as u8,
849 0, 5, b'h', b'e', b'l', b'l', b'o',
851 0, 1, b'b',
853 Amf0Marker::String as u8,
854 0, 5, b'w', b'o', b'r', b'l', b'd',
856 0, 0, Amf0Marker::ObjectEnd as u8,
857 ];
858 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
859 assert_eq!(
860 value,
861 Test::B {
862 a: "hello".to_string(),
863 b: "world".to_string()
864 }
865 );
866
867 #[rustfmt::skip]
868 let bytes = [
869 Amf0Marker::String as u8,
870 0, 1, b'C',
872 Amf0Marker::StrictArray as u8,
873 0, 0, 0, 2, Amf0Marker::Boolean as u8,
875 1,
876 Amf0Marker::String as u8,
877 0, 5, b'h', b'e', b'l', b'l', b'o',
879 ];
880 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
881 assert_eq!(value, Test::C(true, "hello".to_string()));
882 }
883
884 #[test]
885 fn series() {
886 #[rustfmt::skip]
887 let mut bytes = vec![
888 Amf0Marker::String as u8,
889 0, 5, b'h', b'e', b'l', b'l', b'o',
891 Amf0Marker::Boolean as u8,
892 1,
893 Amf0Marker::Number as u8,
894 ];
895 bytes.extend_from_slice(&f64::consts::PI.to_be_bytes());
896
897 let mut de = Amf0Decoder::from_buf(Bytes::from_owner(bytes));
898 let value: String = serde::de::Deserialize::deserialize(&mut de).unwrap();
899 assert_eq!(value, "hello");
900 let value: bool = serde::de::Deserialize::deserialize(&mut de).unwrap();
901 assert!(value);
902 let value: f64 = serde::de::Deserialize::deserialize(&mut de).unwrap();
903 assert_eq!(value, f64::consts::PI);
904 }
905
906 #[test]
907 fn flatten() {
908 #[rustfmt::skip]
909 let bytes = [
910 Amf0Marker::Object as u8,
911 0, 1, b'a',
913 Amf0Marker::Boolean as u8,
914 1,
915 0, 1, b'b',
917 Amf0Marker::String as u8,
918 0, 1, b'b',
920 0, 1, b'c',
922 Amf0Marker::String as u8,
923 0, 1, b'c',
925 0, 0, Amf0Marker::ObjectEnd as u8,
926 ];
927
928 #[derive(Deserialize, Debug, PartialEq)]
929 struct Test<'a> {
930 b: String,
931 #[serde(flatten, borrow)]
932 other: HashMap<StringCow<'a>, Amf0Value<'a>>,
933 }
934
935 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
936 assert_eq!(
937 value,
938 Test {
939 b: "b".to_string(),
940 other: vec![
941 ("a".into(), Amf0Value::from(true)),
942 ("c".into(), StringCow::from_static("c").into())
943 ]
944 .into_iter()
945 .collect(),
946 }
947 );
948 }
949
950 #[test]
951 fn all() {
952 let bytes = [
953 Amf0Marker::String as u8,
954 0,
955 5, b'h',
957 b'e',
958 b'l',
959 b'l',
960 b'o',
961 Amf0Marker::Boolean as u8,
962 1,
963 Amf0Marker::Object as u8,
964 0,
965 1, b'a',
967 Amf0Marker::Boolean as u8,
968 1,
969 0,
970 0,
971 Amf0Marker::ObjectEnd as u8,
972 ];
973
974 let mut de = Amf0Decoder::from_buf(Bytes::from_owner(bytes));
975 let values = de.decode_all().unwrap();
976 assert_eq!(
977 values,
978 vec![
979 Amf0Value::String("hello".into()),
980 Amf0Value::Boolean(true),
981 Amf0Value::Object([("a".into(), Amf0Value::Boolean(true))].into_iter().collect())
982 ]
983 );
984 }
985
986 #[test]
987 fn multi_value() {
988 #[rustfmt::skip]
989 let bytes = [
990 Amf0Marker::String as u8,
991 0, 5, b'h', b'e', b'l', b'l', b'o',
993 Amf0Marker::Boolean as u8,
994 1,
995 Amf0Marker::Object as u8,
996 0, 1, b'a',
998 Amf0Marker::Boolean as u8,
999 1,
1000 0, 0, Amf0Marker::ObjectEnd as u8,
1001 ];
1002
1003 let mut de = Amf0Decoder::from_buf(Bytes::from_owner(bytes));
1004 let values: MultiValue<(String, bool, Amf0Object)> = de.deserialize().unwrap();
1005 assert_eq!(values.0.0, "hello");
1006 assert!(values.0.1);
1007 assert_eq!(
1008 values.0.2,
1009 [("a".into(), Amf0Value::Boolean(true))].into_iter().collect::<Amf0Object>()
1010 );
1011 }
1012
1013 #[test]
1014 fn deserializer_stream() {
1015 #[rustfmt::skip]
1016 let bytes = [
1017 Amf0Marker::String as u8,
1018 0, 5, b'h', b'e', b'l', b'l', b'o',
1020 Amf0Marker::String as u8,
1021 0, 5, b'w', b'o', b'r', b'l', b'd',
1023 Amf0Marker::String as u8,
1024 0, 1, b'a',
1026 ];
1027
1028 let mut de = Amf0Decoder::from_buf(Bytes::from_owner(bytes));
1029 let mut stream = de.deserialize_stream::<String>();
1030 assert_eq!(stream.next().unwrap().unwrap(), "hello");
1031 assert_eq!(stream.next().unwrap().unwrap(), "world");
1032 assert_eq!(stream.next().unwrap().unwrap(), "a");
1033 assert_eq!(stream.next().transpose().unwrap(), None);
1034 }
1035}