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