scuffle_amf0/
ser.rs

1//! Serialize a Rust data structure into AMF0 data.
2
3use std::io;
4
5use serde::Serialize;
6use serde::ser::{
7    Impossible, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple, SerializeTupleStruct,
8    SerializeTupleVariant,
9};
10
11use crate::Amf0Error;
12use crate::encoder::Amf0Encoder;
13
14/// Serialize a value into a given writer.
15pub fn to_writer<W>(writer: W, value: &impl serde::Serialize) -> crate::Result<()>
16where
17    W: io::Write,
18{
19    let mut serializer = Amf0Encoder::new(writer);
20    value.serialize(&mut serializer)
21}
22
23/// Serialize a value into a new byte vector.
24pub fn to_bytes(value: &impl serde::Serialize) -> crate::Result<Vec<u8>> {
25    let mut writer = Vec::new();
26    to_writer(&mut writer, value)?;
27    Ok(writer)
28}
29
30impl<W> serde::ser::Serializer for &mut Amf0Encoder<W>
31where
32    W: io::Write,
33{
34    type Error = Amf0Error;
35    type Ok = ();
36    type SerializeMap = Self;
37    type SerializeSeq = Self;
38    type SerializeStruct = Self;
39    type SerializeStructVariant = Self;
40    type SerializeTuple = Self;
41    type SerializeTupleStruct = Self;
42    type SerializeTupleVariant = Self;
43
44    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
45        self.encode_boolean(v)
46    }
47
48    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
49        self.serialize_f64(v as f64)
50    }
51
52    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
53        self.serialize_f64(v as f64)
54    }
55
56    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
57        self.serialize_f64(v as f64)
58    }
59
60    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
61        self.serialize_f64(v as f64)
62    }
63
64    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
65        self.serialize_f64(v as f64)
66    }
67
68    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
69        self.serialize_f64(v as f64)
70    }
71
72    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
73        self.serialize_f64(v as f64)
74    }
75
76    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
77        self.serialize_f64(v as f64)
78    }
79
80    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
81        self.serialize_f64(v as f64)
82    }
83
84    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
85        self.encode_number(v)
86    }
87
88    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
89        self.serialize_u8(v as u8)
90    }
91
92    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
93        self.encode_string(v)
94    }
95
96    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
97        let mut seq = self.serialize_seq(Some(v.len()))?;
98
99        for b in v {
100            SerializeSeq::serialize_element(&mut seq, b)?;
101        }
102
103        SerializeSeq::end(seq)
104    }
105
106    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
107        // Serialize None as null
108        self.serialize_unit()
109    }
110
111    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
112    where
113        T: ?Sized + serde::Serialize,
114    {
115        // Serialize Some as the inner value
116        value.serialize(self)
117    }
118
119    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
120        // Serialize unit as null
121        self.encode_null()
122    }
123
124    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
125        let len = len.ok_or(Amf0Error::UnknownLength)?.try_into()?;
126        self.encode_array_header(len)?;
127        Ok(self)
128    }
129
130    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
131        // Serialize tuples as arrays
132        self.serialize_seq(Some(len))
133    }
134
135    fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeTupleStruct, Self::Error> {
136        // Serialize tuple structs as arrays
137        self.serialize_seq(Some(len))
138    }
139
140    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
141        self.encode_object_header()?;
142        Ok(self)
143    }
144
145    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
146        // Serialize unit structs as null
147        self.serialize_unit()
148    }
149
150    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Self::Ok, Self::Error>
151    where
152        T: ?Sized + serde::Serialize,
153    {
154        // Serialize newtype structs as the inner value
155        value.serialize(self)
156    }
157
158    fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct, Self::Error> {
159        // Serialize structs as objects
160        self.serialize_map(Some(len))
161    }
162
163    fn serialize_unit_variant(
164        self,
165        _name: &'static str,
166        _variant_index: u32,
167        variant: &'static str,
168    ) -> Result<Self::Ok, Self::Error> {
169        // Serialize unit variants as strings
170        self.serialize_str(variant)
171    }
172
173    fn serialize_newtype_variant<T>(
174        self,
175        _name: &'static str,
176        _variant_index: u32,
177        variant: &'static str,
178        value: &T,
179    ) -> Result<Self::Ok, Self::Error>
180    where
181        T: ?Sized + serde::Serialize,
182    {
183        variant.serialize(&mut *self)?;
184        value.serialize(&mut *self)?;
185
186        Ok(())
187    }
188
189    fn serialize_tuple_variant(
190        self,
191        _name: &'static str,
192        _variant_index: u32,
193        variant: &'static str,
194        len: usize,
195    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
196        let len: u32 = len.try_into()?;
197
198        variant.serialize(&mut *self)?;
199        self.encode_array_header(len)?;
200
201        Ok(self)
202    }
203
204    fn serialize_struct_variant(
205        self,
206        _name: &'static str,
207        _variant_index: u32,
208        variant: &'static str,
209        _len: usize,
210    ) -> Result<Self::SerializeStructVariant, Self::Error> {
211        variant.serialize(&mut *self)?;
212        self.encode_object_header()?;
213
214        Ok(self)
215    }
216
217    fn is_human_readable(&self) -> bool {
218        false
219    }
220}
221
222impl<W> SerializeSeq for &mut Amf0Encoder<W>
223where
224    W: io::Write,
225{
226    type Error = Amf0Error;
227    type Ok = ();
228
229    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
230    where
231        T: ?Sized + serde::Serialize,
232    {
233        value.serialize(&mut **self)
234    }
235
236    fn end(self) -> Result<Self::Ok, Self::Error> {
237        Ok(())
238    }
239}
240
241impl<W> SerializeTuple for &mut Amf0Encoder<W>
242where
243    W: io::Write,
244{
245    type Error = Amf0Error;
246    type Ok = ();
247
248    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
249    where
250        T: ?Sized + serde::Serialize,
251    {
252        value.serialize(&mut **self)
253    }
254
255    fn end(self) -> Result<Self::Ok, Self::Error> {
256        Ok(())
257    }
258}
259
260impl<W> SerializeTupleStruct for &mut Amf0Encoder<W>
261where
262    W: io::Write,
263{
264    type Error = Amf0Error;
265    type Ok = ();
266
267    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
268    where
269        T: ?Sized + serde::Serialize,
270    {
271        value.serialize(&mut **self)
272    }
273
274    fn end(self) -> Result<Self::Ok, Self::Error> {
275        Ok(())
276    }
277}
278
279impl<W> SerializeMap for &mut Amf0Encoder<W>
280where
281    W: io::Write,
282{
283    type Error = Amf0Error;
284    type Ok = ();
285
286    fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
287    where
288        T: ?Sized + serde::Serialize,
289    {
290        key.serialize(&mut MapKeySerializer { ser: self })
291    }
292
293    fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
294    where
295        T: ?Sized + serde::Serialize,
296    {
297        value.serialize(&mut **self)
298    }
299
300    fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<(), Self::Error>
301    where
302        K: ?Sized + serde::Serialize,
303        V: ?Sized + serde::Serialize,
304    {
305        self.serialize_key(key)?;
306        self.serialize_value(value)?;
307
308        Ok(())
309    }
310
311    fn end(self) -> Result<Self::Ok, Self::Error> {
312        self.encode_object_trailer()
313    }
314}
315
316impl<W> SerializeStruct for &mut Amf0Encoder<W>
317where
318    W: io::Write,
319{
320    type Error = Amf0Error;
321    type Ok = ();
322
323    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
324    where
325        T: ?Sized + serde::Serialize,
326    {
327        key.serialize(&mut MapKeySerializer { ser: *self })?;
328        value.serialize(&mut **self)?;
329
330        Ok(())
331    }
332
333    fn end(self) -> Result<Self::Ok, Self::Error> {
334        self.encode_object_trailer()
335    }
336}
337
338struct MapKeySerializer<'a, W> {
339    ser: &'a mut Amf0Encoder<W>,
340}
341
342impl<W> serde::ser::Serializer for &mut MapKeySerializer<'_, W>
343where
344    W: io::Write,
345{
346    type Error = Amf0Error;
347    type Ok = ();
348    type SerializeMap = Impossible<Self::Ok, Self::Error>;
349    type SerializeSeq = Impossible<Self::Ok, Self::Error>;
350    type SerializeStruct = Impossible<Self::Ok, Self::Error>;
351    type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;
352    type SerializeTuple = Impossible<Self::Ok, Self::Error>;
353    type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
354    type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
355
356    fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
357        Err(Amf0Error::MapKeyNotString)
358    }
359
360    fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
361        Err(Amf0Error::MapKeyNotString)
362    }
363
364    fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
365        Err(Amf0Error::MapKeyNotString)
366    }
367
368    fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
369        Err(Amf0Error::MapKeyNotString)
370    }
371
372    fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
373        Err(Amf0Error::MapKeyNotString)
374    }
375
376    fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
377        Err(Amf0Error::MapKeyNotString)
378    }
379
380    fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
381        Err(Amf0Error::MapKeyNotString)
382    }
383
384    fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
385        Err(Amf0Error::MapKeyNotString)
386    }
387
388    fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
389        Err(Amf0Error::MapKeyNotString)
390    }
391
392    fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
393        Err(Amf0Error::MapKeyNotString)
394    }
395
396    fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
397        Err(Amf0Error::MapKeyNotString)
398    }
399
400    fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
401        Err(Amf0Error::MapKeyNotString)
402    }
403
404    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
405        self.ser.encode_object_key(v)
406    }
407
408    fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
409        Err(Amf0Error::MapKeyNotString)
410    }
411
412    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
413        Err(Amf0Error::MapKeyNotString)
414    }
415
416    fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
417    where
418        T: ?Sized + serde::Serialize,
419    {
420        Err(Amf0Error::MapKeyNotString)
421    }
422
423    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
424        Err(Amf0Error::MapKeyNotString)
425    }
426
427    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
428        Err(Amf0Error::MapKeyNotString)
429    }
430
431    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
432        Err(Amf0Error::MapKeyNotString)
433    }
434
435    fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeTupleStruct, Self::Error> {
436        Err(Amf0Error::MapKeyNotString)
437    }
438
439    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
440        Err(Amf0Error::MapKeyNotString)
441    }
442
443    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
444        Err(Amf0Error::MapKeyNotString)
445    }
446
447    fn serialize_newtype_struct<T>(self, _name: &'static str, _value: &T) -> Result<Self::Ok, Self::Error>
448    where
449        T: ?Sized + serde::Serialize,
450    {
451        Err(Amf0Error::MapKeyNotString)
452    }
453
454    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct, Self::Error> {
455        Err(Amf0Error::MapKeyNotString)
456    }
457
458    fn serialize_unit_variant(
459        self,
460        _name: &'static str,
461        _variant_index: u32,
462        _variant: &'static str,
463    ) -> Result<Self::Ok, Self::Error> {
464        Err(Amf0Error::MapKeyNotString)
465    }
466
467    fn serialize_newtype_variant<T>(
468        self,
469        _name: &'static str,
470        _variant_index: u32,
471        _variant: &'static str,
472        _value: &T,
473    ) -> Result<Self::Ok, Self::Error>
474    where
475        T: ?Sized + serde::Serialize,
476    {
477        Err(Amf0Error::MapKeyNotString)
478    }
479
480    fn serialize_tuple_variant(
481        self,
482        _name: &'static str,
483        _variant_index: u32,
484        _variant: &'static str,
485        _len: usize,
486    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
487        Err(Amf0Error::MapKeyNotString)
488    }
489
490    fn serialize_struct_variant(
491        self,
492        _name: &'static str,
493        _variant_index: u32,
494        _variant: &'static str,
495        _len: usize,
496    ) -> Result<Self::SerializeStructVariant, Self::Error> {
497        Err(Amf0Error::MapKeyNotString)
498    }
499
500    fn is_human_readable(&self) -> bool {
501        false
502    }
503}
504
505impl<W> SerializeTupleVariant for &mut Amf0Encoder<W>
506where
507    W: io::Write,
508{
509    type Error = Amf0Error;
510    type Ok = ();
511
512    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
513    where
514        T: ?Sized + serde::Serialize,
515    {
516        value.serialize(&mut **self)
517    }
518
519    fn end(self) -> Result<Self::Ok, Self::Error> {
520        Ok(())
521    }
522}
523
524impl<W> SerializeStructVariant for &mut Amf0Encoder<W>
525where
526    W: io::Write,
527{
528    type Error = Amf0Error;
529    type Ok = ();
530
531    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
532    where
533        T: ?Sized + Serialize,
534    {
535        key.serialize(&mut MapKeySerializer { ser: *self })?;
536        value.serialize(&mut **self)?;
537
538        Ok(())
539    }
540
541    fn end(self) -> Result<Self::Ok, Self::Error> {
542        self.encode_object_trailer()
543    }
544}
545
546#[cfg(test)]
547#[cfg_attr(all(test, coverage_nightly), coverage(off))]
548mod tests {
549    use std::collections::HashMap;
550    use std::hash::Hash;
551
552    use serde_derive::Serialize;
553
554    use crate::{Amf0Error, Amf0Marker, Amf0Value, to_bytes};
555
556    #[test]
557    fn string() {
558        let value = "hello";
559        let bytes = to_bytes(&value).unwrap();
560
561        #[rustfmt::skip]
562        assert_eq!(
563            bytes,
564            [
565                Amf0Marker::String as u8,
566                0, 5, // length
567                b'h', b'e', b'l', b'l', b'o',
568            ]
569        );
570
571        let value = "a".repeat(u16::MAX as usize + 1);
572        let bytes = to_bytes(&value).unwrap();
573
574        let mut expected = vec![Amf0Marker::LongString as u8];
575        expected.extend_from_slice(&(value.len() as u32).to_be_bytes());
576        expected.extend(value.as_bytes());
577        assert_eq!(bytes, expected);
578    }
579
580    #[test]
581    fn char() {
582        let value = 'a';
583        let bytes = to_bytes(&value).unwrap();
584
585        let mut expected = vec![Amf0Marker::Number as u8];
586        expected.extend((b'a' as f64).to_be_bytes());
587        #[rustfmt::skip]
588        assert_eq!(bytes, expected);
589    }
590
591    #[test]
592    fn bool() {
593        let bytes = to_bytes(&true).unwrap();
594        assert_eq!(bytes, [Amf0Marker::Boolean as u8, 1]);
595
596        let bytes = to_bytes(&false).unwrap();
597        assert_eq!(bytes, [Amf0Marker::Boolean as u8, 0]);
598    }
599
600    #[test]
601    fn optional() {
602        let bytes = to_bytes(&()).unwrap();
603        assert_eq!(bytes, [Amf0Marker::Null as u8]);
604
605        let bytes = to_bytes(&None::<String>).unwrap();
606        assert_eq!(bytes, [Amf0Marker::Null as u8]);
607
608        #[derive(Serialize)]
609        struct Unit;
610        let bytes = to_bytes(&Unit).unwrap();
611        assert_eq!(bytes, [Amf0Marker::Null as u8]);
612
613        let bytes = to_bytes(&Some("abc")).unwrap();
614        assert_eq!(bytes, [Amf0Marker::String as u8, 0, 3, b'a', b'b', b'c']);
615    }
616
617    #[test]
618    fn tuple_struct() {
619        #[derive(Serialize)]
620        struct TupleStruct(String, String);
621
622        let value = TupleStruct("hello".to_string(), "world".to_string());
623        let bytes = to_bytes(&value).unwrap();
624
625        #[rustfmt::skip]
626        assert_eq!(
627            bytes,
628            [
629                Amf0Marker::StrictArray as u8,
630                0, 0, 0, 2, // array length
631                Amf0Marker::String as u8,
632                0, 5, // length
633                b'h', b'e', b'l', b'l', b'o',
634                Amf0Marker::String as u8,
635                0, 5, // length
636                b'w', b'o', b'r', b'l', b'd',
637            ]
638        );
639    }
640
641    #[test]
642    fn newtype_struct() {
643        #[derive(Serialize)]
644        struct NewtypeStruct(String);
645
646        let value = NewtypeStruct("hello".to_string());
647        let bytes = to_bytes(&value).unwrap();
648
649        #[rustfmt::skip]
650        assert_eq!(
651            bytes,
652            [
653                Amf0Marker::String as u8,
654                0, 5, // length
655                b'h', b'e', b'l', b'l', b'o',
656            ]
657        );
658    }
659
660    #[test]
661    fn array() {
662        let vec = vec![false, true, false];
663        let bytes = to_bytes(&vec).unwrap();
664        #[rustfmt::skip]
665        assert_eq!(
666            bytes,
667            [
668                Amf0Marker::StrictArray as u8,
669                0, 0, 0, 3, // array length
670                Amf0Marker::Boolean as u8,
671                0,
672                Amf0Marker::Boolean as u8,
673                1,
674                Amf0Marker::Boolean as u8,
675                0,
676            ]
677        );
678
679        let byte_vec = vec![0u8, 1]; // 2 bytes
680        let bytes = to_bytes(&byte_vec).unwrap();
681
682        #[rustfmt::skip]
683        let mut expected = vec![
684            Amf0Marker::StrictArray as u8,
685            0, 0, 0, 2, // array length
686            Amf0Marker::Number as u8,
687        ];
688        expected.extend(&0.0f64.to_be_bytes());
689        expected.push(Amf0Marker::Number as u8);
690        expected.extend(&1.0f64.to_be_bytes());
691        assert_eq!(bytes, expected);
692
693        let bytes = to_bytes(&("a", false, true)).unwrap();
694        #[rustfmt::skip]
695        assert_eq!(
696            bytes,
697            [
698                Amf0Marker::StrictArray as u8,
699                0, 0, 0, 3, // array length
700                Amf0Marker::String as u8,
701                0, 1, // length
702                b'a',
703                Amf0Marker::Boolean as u8,
704                0,
705                Amf0Marker::Boolean as u8,
706                1,
707            ]
708        );
709    }
710
711    fn number_test<T>(one: T)
712    where
713        T: serde::Serialize,
714    {
715        let bytes = to_bytes(&one).unwrap();
716        let mut expected = vec![Amf0Marker::Number as u8];
717        expected.extend(&1.0f64.to_be_bytes());
718        assert_eq!(bytes, expected);
719    }
720
721    #[test]
722    fn numbers() {
723        number_test(1u8);
724        number_test(1u16);
725        number_test(1u32);
726        number_test(1u64);
727        number_test(1i8);
728        number_test(1i16);
729        number_test(1i32);
730        number_test(1i64);
731        number_test(1.0f32);
732        number_test(1.0f64);
733    }
734
735    #[test]
736    fn simple_struct() {
737        #[derive(Serialize)]
738        struct Test {
739            a: f64,
740            b: String,
741        }
742
743        let value = Test {
744            a: 1.0,
745            b: "hello".to_string(),
746        };
747
748        let bytes = to_bytes(&value).unwrap();
749
750        #[rustfmt::skip]
751        let mut expected = vec![
752            Amf0Marker::Object as u8,
753            0, 1, // length
754            b'a',
755            Amf0Marker::Number as u8,
756        ];
757        expected.extend(&1.0f64.to_be_bytes());
758        #[rustfmt::skip]
759        expected.extend_from_slice(&[
760            0, 1, // length
761            b'b',
762            Amf0Marker::String as u8,
763            0, 5, // length
764            b'h', b'e', b'l', b'l', b'o',
765            0, 0, Amf0Marker::ObjectEnd as u8,
766        ]);
767        assert_eq!(bytes, expected);
768    }
769
770    #[test]
771    fn simple_enum() {
772        #[derive(Serialize)]
773        enum Test {
774            A,
775            B,
776        }
777
778        let value = Test::A;
779        let bytes = to_bytes(&value).unwrap();
780
781        #[rustfmt::skip]
782        let expected = vec![
783            Amf0Marker::String as u8,
784            0, 1, // length
785            b'A',
786        ];
787        assert_eq!(bytes, expected);
788
789        let value = Test::B;
790        let bytes = to_bytes(&value).unwrap();
791
792        #[rustfmt::skip]
793        let expected = vec![
794            Amf0Marker::String as u8,
795            0, 1, // length
796            b'B',
797        ];
798        assert_eq!(bytes, expected);
799    }
800
801    #[test]
802    fn complex_enum() {
803        #[derive(Serialize)]
804        enum Test {
805            A(bool),
806            B { a: String, b: String },
807            C(bool, String),
808        }
809
810        let value = Test::A(true);
811        let bytes = to_bytes(&value).unwrap();
812        #[rustfmt::skip]
813        let expected = vec![
814            Amf0Marker::String as u8,
815            0, 1, // length
816            b'A',
817            Amf0Marker::Boolean as u8,
818            1,
819        ];
820        assert_eq!(bytes, expected);
821
822        let value = Test::B {
823            a: "hello".to_string(),
824            b: "world".to_string(),
825        };
826        let bytes = to_bytes(&value).unwrap();
827        #[rustfmt::skip]
828        let expected = vec![
829            Amf0Marker::String as u8,
830            0, 1, // length
831            b'B',
832            Amf0Marker::Object as u8,
833            0, 1, // length
834            b'a',
835            Amf0Marker::String as u8,
836            0, 5, // length
837            b'h', b'e', b'l', b'l', b'o',
838            0, 1, // length
839            b'b',
840            Amf0Marker::String as u8,
841            0, 5, // length
842            b'w', b'o', b'r', b'l', b'd',
843            0, 0, Amf0Marker::ObjectEnd as u8,
844        ];
845        assert_eq!(bytes, expected);
846
847        let value = Test::C(true, "hello".to_string());
848        let bytes = to_bytes(&value).unwrap();
849        #[rustfmt::skip]
850        let expected = vec![
851            Amf0Marker::String as u8,
852            0, 1, // length
853            b'C',
854            Amf0Marker::StrictArray as u8,
855            0, 0, 0, 2, // array length
856            Amf0Marker::Boolean as u8,
857            1,
858            Amf0Marker::String as u8,
859            0, 5, // length
860            b'h', b'e', b'l', b'l', b'o',
861        ];
862        assert_eq!(bytes, expected);
863    }
864
865    fn test_invalid_map_key<T>(key: T)
866    where
867        T: Eq + Hash + serde::Serialize,
868    {
869        let mut map = HashMap::new();
870        map.insert(key, Amf0Value::Number(1.0));
871        let err = to_bytes(&map).unwrap_err();
872        assert!(matches!(err, Amf0Error::MapKeyNotString));
873    }
874
875    #[test]
876    fn invalid_map_keys() {
877        test_invalid_map_key(false);
878
879        test_invalid_map_key(1u8);
880        test_invalid_map_key(1u16);
881        test_invalid_map_key(1u32);
882        test_invalid_map_key(1u64);
883
884        test_invalid_map_key(1i8);
885        test_invalid_map_key(1i16);
886        test_invalid_map_key(1i32);
887        test_invalid_map_key(1i64);
888
889        test_invalid_map_key('a');
890
891        test_invalid_map_key([1u8, 2, 3]);
892
893        test_invalid_map_key(None::<String>);
894        test_invalid_map_key(Some("hello"));
895        test_invalid_map_key(());
896
897        test_invalid_map_key(vec![1, 2, 3]);
898        test_invalid_map_key((1, 2, 3));
899
900        #[derive(Serialize, Eq, PartialEq, Hash)]
901        struct Tuple(String, String);
902        test_invalid_map_key(Tuple("hello".to_string(), "world".to_string()));
903
904        #[derive(Serialize, Eq, PartialEq, Hash)]
905        struct Struct {
906            a: String,
907        }
908        test_invalid_map_key(Struct { a: "hello".to_string() });
909
910        #[derive(Serialize, Eq, PartialEq, Hash)]
911        struct Unit;
912        test_invalid_map_key(Unit);
913
914        #[derive(Serialize, Eq, PartialEq, Hash)]
915        struct Newtype(String);
916        test_invalid_map_key(Newtype("hello".to_string()));
917
918        #[derive(Serialize, Eq, PartialEq, Hash)]
919        enum Enum {
920            A,
921            B(bool),
922            C(String, String),
923            D { a: String },
924        }
925        test_invalid_map_key(Enum::A);
926        test_invalid_map_key(Enum::B(true));
927        test_invalid_map_key(Enum::C("hello".to_string(), "world".to_string()));
928        test_invalid_map_key(Enum::D { a: "hello".to_string() });
929    }
930}