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
488 use crate::de::MultiValue;
489 use crate::decoder::Amf0Decoder;
490 use crate::{Amf0Error, Amf0Marker, Amf0Object, Amf0Value, from_buf};
491
492 #[test]
493 fn string() {
494 #[rustfmt::skip]
495 let bytes = [
496 Amf0Marker::String as u8,
497 0, 5, b'h', b'e', b'l', b'l', b'o',
499 ];
500
501 let value: String = from_buf(Bytes::from_owner(bytes)).unwrap();
502 assert_eq!(value, "hello");
503
504 #[rustfmt::skip]
505 let bytes = [
506 Amf0Marker::LongString as u8,
507 0, 0, 0, 5, b'h', b'e', b'l', b'l', b'o',
509 ];
510
511 let value: String = from_buf(Bytes::from_owner(bytes)).unwrap();
512 assert_eq!(value, "hello");
513
514 let bytes = [Amf0Marker::Boolean as u8];
515 let err = from_buf::<String>(Bytes::from_owner(bytes)).unwrap_err();
516 assert!(matches!(
517 err,
518 Amf0Error::UnexpectedType {
519 expected: [Amf0Marker::String, Amf0Marker::LongString, Amf0Marker::XmlDocument],
520 got: Amf0Marker::Boolean
521 }
522 ));
523 }
524
525 #[test]
526 fn bool() {
527 let bytes = [Amf0Marker::Boolean as u8, 1];
528 let value: bool = from_buf(Bytes::from_owner(bytes)).unwrap();
529 assert!(value);
530
531 let bytes = [Amf0Marker::String as u8];
532 let err = from_buf::<bool>(Bytes::from_owner(bytes)).unwrap_err();
533 assert!(matches!(
534 err,
535 Amf0Error::UnexpectedType {
536 expected: [Amf0Marker::Boolean],
537 got: Amf0Marker::String
538 }
539 ));
540 }
541
542 fn number_test<'de, T>(one: T)
543 where
544 T: serde::Deserialize<'de> + PartialEq + Debug,
545 {
546 const NUMBER_ONE: [u8; 9] = const {
547 let one = 1.0f64.to_be_bytes();
548 [
549 Amf0Marker::Number as u8,
550 one[0],
551 one[1],
552 one[2],
553 one[3],
554 one[4],
555 one[5],
556 one[6],
557 one[7],
558 ]
559 };
560
561 let value: T = from_buf(Bytes::from_static(&NUMBER_ONE)).unwrap();
562 assert_eq!(value, one);
563 }
564
565 #[test]
566 fn numbers() {
567 number_test(1u8);
568 number_test(1u16);
569 number_test(1u32);
570 number_test(1u64);
571 number_test(1i8);
572 number_test(1i16);
573 number_test(1i32);
574 number_test(1i64);
575 number_test(1f32);
576 number_test(1f64);
577
578 let mut bytes = vec![Amf0Marker::Date as u8];
579 bytes.extend_from_slice(&f64::consts::PI.to_be_bytes());
580 bytes.extend_from_slice(&0u16.to_be_bytes()); let value: f64 = from_buf(Bytes::from_owner(bytes)).unwrap();
582 assert_eq!(value, f64::consts::PI);
583
584 let bytes = [Amf0Marker::Boolean as u8];
585 let err = from_buf::<f64>(Bytes::from_owner(bytes)).unwrap_err();
586 assert!(matches!(
587 err,
588 Amf0Error::UnexpectedType {
589 expected: [Amf0Marker::Number, Amf0Marker::Date],
590 got: Amf0Marker::Boolean
591 }
592 ));
593 }
594
595 #[test]
596 fn char() {
597 let err = from_buf::<char>(Bytes::from_owner([])).unwrap_err();
598 assert!(matches!(err, Amf0Error::CharNotSupported));
599 }
600
601 #[test]
602 fn optional() {
603 let bytes = [Amf0Marker::Null as u8];
604 let value: Option<bool> = from_buf(Bytes::from_owner(bytes)).unwrap();
605 assert_eq!(value, None);
606
607 let bytes = [Amf0Marker::Null as u8];
608 from_buf::<()>(Bytes::from_owner(bytes)).unwrap();
609
610 let bytes = [Amf0Marker::String as u8];
611 let err = from_buf::<()>(Bytes::from_owner(bytes)).unwrap_err();
612 assert!(matches!(
613 err,
614 Amf0Error::UnexpectedType {
615 expected: [Amf0Marker::Null, Amf0Marker::Undefined],
616 got: Amf0Marker::String
617 }
618 ));
619
620 let bytes = [Amf0Marker::Undefined as u8];
621 let value: Option<bool> = from_buf(Bytes::from_owner(bytes)).unwrap();
622 assert_eq!(value, None);
623
624 let bytes = [Amf0Marker::Boolean as u8, 0];
625 let value: Option<bool> = from_buf(Bytes::from_owner(bytes)).unwrap();
626 assert_eq!(value, Some(false));
627
628 #[derive(serde::Deserialize, PartialEq, Debug)]
629 struct Unit;
630
631 let bytes = [Amf0Marker::Null as u8];
632 let value: Unit = from_buf(Bytes::from_owner(bytes)).unwrap();
633 assert_eq!(value, Unit);
634 }
635
636 #[test]
637 fn newtype_struct() {
638 #[derive(serde::Deserialize, Debug, PartialEq)]
639 struct Test(String);
640
641 #[rustfmt::skip]
642 let bytes = [
643 Amf0Marker::String as u8,
644 0, 5, b'h', b'e', b'l', b'l', b'o',
646 ];
647 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
648 assert_eq!(value, Test("hello".to_string()));
649 }
650
651 #[test]
652 fn tuple_struct() {
653 #[derive(serde::Deserialize, Debug, PartialEq)]
654 struct Test(bool, String);
655
656 #[rustfmt::skip]
657 let bytes = [
658 Amf0Marker::StrictArray as u8,
659 0, 0, 0, 2, Amf0Marker::Boolean as u8,
661 1,
662 Amf0Marker::String as u8,
663 0, 5, b'h', b'e', b'l', b'l', b'o',
665 ];
666 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
667 assert_eq!(value, Test(true, "hello".to_string()));
668
669 #[rustfmt::skip]
670 let bytes = [
671 Amf0Marker::StrictArray as u8,
672 0, 0, 0, 1, Amf0Marker::Boolean as u8,
674 1,
675 ];
676 let err = from_buf::<Test>(Bytes::from_owner(bytes)).unwrap_err();
677 assert!(matches!(err, Amf0Error::WrongArrayLength { expected: 2, got: 1 }));
678 }
679
680 #[test]
681 fn typed_object() {
682 #[derive(serde::Deserialize, Debug, PartialEq)]
683 struct Test {
684 a: bool,
685 b: String,
686 }
687
688 #[rustfmt::skip]
689 let bytes = [
690 Amf0Marker::TypedObject as u8,
691 0, 1, b'a', 0, 1, b'a', Amf0Marker::Boolean as u8,
696 1,
697 0, 1, b'b', Amf0Marker::String as u8,
700 0, 5, b'h', b'e', b'l', b'l', b'o',
702 0, 0, Amf0Marker::ObjectEnd as u8,
703 ];
704 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
705 assert_eq!(
706 value,
707 Test {
708 a: true,
709 b: "hello".to_string()
710 }
711 );
712 }
713
714 #[test]
715 fn simple_struct() {
716 #[derive(serde::Deserialize, Debug, PartialEq)]
717 struct Test {
718 a: bool,
719 b: String,
720 c: f64,
721 }
722
723 #[rustfmt::skip]
724 let mut bytes = vec![
725 Amf0Marker::Object as u8,
726 0, 1, b'a', Amf0Marker::Boolean as u8, 1,
730 0, 1, b'b', Amf0Marker::String as u8, 0, 1, b'b', 0, 1, b'c', Amf0Marker::Number as u8, ];
739 bytes.extend_from_slice(&f64::consts::PI.to_be_bytes());
740 bytes.extend_from_slice(&[0, 0, Amf0Marker::ObjectEnd as u8]);
741 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
742
743 assert_eq!(
744 value,
745 Test {
746 a: true,
747 b: "b".to_string(),
748 c: f64::consts::PI,
749 }
750 );
751
752 #[rustfmt::skip]
753 let mut bytes = vec![
754 Amf0Marker::EcmaArray as u8,
755 0, 0, 0, 3, 0, 1, b'a', Amf0Marker::Boolean as u8, 1,
760 0, 1, b'b', Amf0Marker::String as u8, 0, 1, b'b', 0, 1, b'c', Amf0Marker::Number as u8, ];
769 bytes.extend_from_slice(&f64::consts::PI.to_be_bytes());
770 bytes.extend_from_slice(&[0, 0, 0]); let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
772
773 assert_eq!(
774 value,
775 Test {
776 a: true,
777 b: "b".to_string(),
778 c: f64::consts::PI,
779 }
780 );
781
782 let err = from_buf::<Test>(Bytes::from_owner([Amf0Marker::String as u8])).unwrap_err();
783 assert!(matches!(
784 err,
785 Amf0Error::UnexpectedType {
786 expected: [Amf0Marker::Object, Amf0Marker::TypedObject, Amf0Marker::EcmaArray],
787 got: Amf0Marker::String
788 }
789 ));
790 }
791
792 #[test]
793 fn simple_enum() {
794 #[derive(serde::Deserialize, Debug, PartialEq)]
795 enum Test {
796 A,
797 B,
798 }
799
800 #[rustfmt::skip]
801 let bytes = vec![
802 Amf0Marker::String as u8,
803 0, 1, b'A',
805 ];
806 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
807 assert_eq!(value, Test::A);
808
809 #[rustfmt::skip]
810 let bytes = vec![
811 Amf0Marker::String as u8,
812 0, 1, b'B',
814 ];
815 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
816 assert_eq!(value, Test::B);
817 }
818
819 #[test]
820 fn complex_enum() {
821 #[derive(serde::Deserialize, Debug, PartialEq)]
822 enum Test {
823 A(bool),
824 B { a: String, b: String },
825 C(bool, String),
826 }
827
828 #[rustfmt::skip]
829 let bytes = [
830 Amf0Marker::String as u8,
831 0, 1, b'A',
833 Amf0Marker::Boolean as u8,
834 1,
835 ];
836 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
837 assert_eq!(value, Test::A(true));
838
839 #[rustfmt::skip]
840 let bytes = [
841 Amf0Marker::String as u8,
842 0, 1, b'B',
844 Amf0Marker::Object as u8,
845 0, 1, b'a',
847 Amf0Marker::String as u8,
848 0, 5, b'h', b'e', b'l', b'l', b'o',
850 0, 1, b'b',
852 Amf0Marker::String as u8,
853 0, 5, b'w', b'o', b'r', b'l', b'd',
855 0, 0, Amf0Marker::ObjectEnd as u8,
856 ];
857 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
858 assert_eq!(
859 value,
860 Test::B {
861 a: "hello".to_string(),
862 b: "world".to_string()
863 }
864 );
865
866 #[rustfmt::skip]
867 let bytes = [
868 Amf0Marker::String as u8,
869 0, 1, b'C',
871 Amf0Marker::StrictArray as u8,
872 0, 0, 0, 2, Amf0Marker::Boolean as u8,
874 1,
875 Amf0Marker::String as u8,
876 0, 5, b'h', b'e', b'l', b'l', b'o',
878 ];
879 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
880 assert_eq!(value, Test::C(true, "hello".to_string()));
881 }
882
883 #[test]
884 fn series() {
885 #[rustfmt::skip]
886 let mut bytes = vec![
887 Amf0Marker::String as u8,
888 0, 5, b'h', b'e', b'l', b'l', b'o',
890 Amf0Marker::Boolean as u8,
891 1,
892 Amf0Marker::Number as u8,
893 ];
894 bytes.extend_from_slice(&f64::consts::PI.to_be_bytes());
895
896 let mut de = Amf0Decoder::from_buf(Bytes::from_owner(bytes));
897 let value: String = serde::de::Deserialize::deserialize(&mut de).unwrap();
898 assert_eq!(value, "hello");
899 let value: bool = serde::de::Deserialize::deserialize(&mut de).unwrap();
900 assert!(value);
901 let value: f64 = serde::de::Deserialize::deserialize(&mut de).unwrap();
902 assert_eq!(value, f64::consts::PI);
903 }
904
905 #[test]
906 fn flatten() {
907 #[rustfmt::skip]
908 let bytes = [
909 Amf0Marker::Object as u8,
910 0, 1, b'a',
912 Amf0Marker::Boolean as u8,
913 1,
914 0, 1, b'b',
916 Amf0Marker::String as u8,
917 0, 1, b'b',
919 0, 1, b'c',
921 Amf0Marker::String as u8,
922 0, 1, b'c',
924 0, 0, Amf0Marker::ObjectEnd as u8,
925 ];
926
927 #[derive(serde::Deserialize, Debug, PartialEq)]
928 struct Test<'a> {
929 b: String,
930 #[serde(flatten, borrow)]
931 other: HashMap<StringCow<'a>, Amf0Value<'a>>,
932 }
933
934 let value: Test = from_buf(Bytes::from_owner(bytes)).unwrap();
935 assert_eq!(
936 value,
937 Test {
938 b: "b".to_string(),
939 other: vec![
940 ("a".into(), Amf0Value::from(true)),
941 ("c".into(), StringCow::from_static("c").into())
942 ]
943 .into_iter()
944 .collect(),
945 }
946 );
947 }
948
949 #[test]
950 fn all() {
951 let bytes = [
952 Amf0Marker::String as u8,
953 0,
954 5, b'h',
956 b'e',
957 b'l',
958 b'l',
959 b'o',
960 Amf0Marker::Boolean as u8,
961 1,
962 Amf0Marker::Object as u8,
963 0,
964 1, b'a',
966 Amf0Marker::Boolean as u8,
967 1,
968 0,
969 0,
970 Amf0Marker::ObjectEnd as u8,
971 ];
972
973 let mut de = Amf0Decoder::from_buf(Bytes::from_owner(bytes));
974 let values = de.decode_all().unwrap();
975 assert_eq!(
976 values,
977 vec![
978 Amf0Value::String("hello".into()),
979 Amf0Value::Boolean(true),
980 Amf0Value::Object([("a".into(), Amf0Value::Boolean(true))].into_iter().collect())
981 ]
982 );
983 }
984
985 #[test]
986 fn multi_value() {
987 #[rustfmt::skip]
988 let bytes = [
989 Amf0Marker::String as u8,
990 0, 5, b'h', b'e', b'l', b'l', b'o',
992 Amf0Marker::Boolean as u8,
993 1,
994 Amf0Marker::Object as u8,
995 0, 1, b'a',
997 Amf0Marker::Boolean as u8,
998 1,
999 0, 0, Amf0Marker::ObjectEnd as u8,
1000 ];
1001
1002 let mut de = Amf0Decoder::from_buf(Bytes::from_owner(bytes));
1003 let values: MultiValue<(String, bool, Amf0Object)> = de.deserialize().unwrap();
1004 assert_eq!(values.0.0, "hello");
1005 assert!(values.0.1);
1006 assert_eq!(
1007 values.0.2,
1008 [("a".into(), Amf0Value::Boolean(true))].into_iter().collect::<Amf0Object>()
1009 );
1010 }
1011
1012 #[test]
1013 fn deserializer_stream() {
1014 #[rustfmt::skip]
1015 let bytes = [
1016 Amf0Marker::String as u8,
1017 0, 5, b'h', b'e', b'l', b'l', b'o',
1019 Amf0Marker::String as u8,
1020 0, 5, b'w', b'o', b'r', b'l', b'd',
1022 Amf0Marker::String as u8,
1023 0, 1, b'a',
1025 ];
1026
1027 let mut de = Amf0Decoder::from_buf(Bytes::from_owner(bytes));
1028 let mut stream = de.deserialize_stream::<String>();
1029 assert_eq!(stream.next().unwrap().unwrap(), "hello");
1030 assert_eq!(stream.next().unwrap().unwrap(), "world");
1031 assert_eq!(stream.next().unwrap().unwrap(), "a");
1032 assert_eq!(stream.next().transpose().unwrap(), None);
1033 }
1034}