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 crate::{Amf0Error, Amf0Marker, Amf0Value, to_bytes};
553
554    #[test]
555    fn string() {
556        let value = "hello";
557        let bytes = to_bytes(&value).unwrap();
558
559        #[rustfmt::skip]
560        assert_eq!(
561            bytes,
562            [
563                Amf0Marker::String as u8,
564                0, 5, // length
565                b'h', b'e', b'l', b'l', b'o',
566            ]
567        );
568
569        let value = "a".repeat(u16::MAX as usize + 1);
570        let bytes = to_bytes(&value).unwrap();
571
572        let mut expected = vec![Amf0Marker::LongString as u8];
573        expected.extend_from_slice(&(value.len() as u32).to_be_bytes());
574        expected.extend(value.as_bytes());
575        assert_eq!(bytes, expected);
576    }
577
578    #[test]
579    fn char() {
580        let value = 'a';
581        let bytes = to_bytes(&value).unwrap();
582
583        let mut expected = vec![Amf0Marker::Number as u8];
584        expected.extend((b'a' as f64).to_be_bytes());
585        #[rustfmt::skip]
586        assert_eq!(bytes, expected);
587    }
588
589    #[test]
590    fn bool() {
591        let bytes = to_bytes(&true).unwrap();
592        assert_eq!(bytes, [Amf0Marker::Boolean as u8, 1]);
593
594        let bytes = to_bytes(&false).unwrap();
595        assert_eq!(bytes, [Amf0Marker::Boolean as u8, 0]);
596    }
597
598    #[test]
599    fn optional() {
600        let bytes = to_bytes(&()).unwrap();
601        assert_eq!(bytes, [Amf0Marker::Null as u8]);
602
603        let bytes = to_bytes(&None::<String>).unwrap();
604        assert_eq!(bytes, [Amf0Marker::Null as u8]);
605
606        #[derive(serde::Serialize)]
607        struct Unit;
608        let bytes = to_bytes(&Unit).unwrap();
609        assert_eq!(bytes, [Amf0Marker::Null as u8]);
610
611        let bytes = to_bytes(&Some("abc")).unwrap();
612        assert_eq!(bytes, [Amf0Marker::String as u8, 0, 3, b'a', b'b', b'c']);
613    }
614
615    #[test]
616    fn tuple_struct() {
617        #[derive(serde::Serialize)]
618        struct TupleStruct(String, String);
619
620        let value = TupleStruct("hello".to_string(), "world".to_string());
621        let bytes = to_bytes(&value).unwrap();
622
623        #[rustfmt::skip]
624        assert_eq!(
625            bytes,
626            [
627                Amf0Marker::StrictArray as u8,
628                0, 0, 0, 2, // array length
629                Amf0Marker::String as u8,
630                0, 5, // length
631                b'h', b'e', b'l', b'l', b'o',
632                Amf0Marker::String as u8,
633                0, 5, // length
634                b'w', b'o', b'r', b'l', b'd',
635            ]
636        );
637    }
638
639    #[test]
640    fn newtype_struct() {
641        #[derive(serde::Serialize)]
642        struct NewtypeStruct(String);
643
644        let value = NewtypeStruct("hello".to_string());
645        let bytes = to_bytes(&value).unwrap();
646
647        #[rustfmt::skip]
648        assert_eq!(
649            bytes,
650            [
651                Amf0Marker::String as u8,
652                0, 5, // length
653                b'h', b'e', b'l', b'l', b'o',
654            ]
655        );
656    }
657
658    #[test]
659    fn array() {
660        let vec = vec![false, true, false];
661        let bytes = to_bytes(&vec).unwrap();
662        #[rustfmt::skip]
663        assert_eq!(
664            bytes,
665            [
666                Amf0Marker::StrictArray as u8,
667                0, 0, 0, 3, // array length
668                Amf0Marker::Boolean as u8,
669                0,
670                Amf0Marker::Boolean as u8,
671                1,
672                Amf0Marker::Boolean as u8,
673                0,
674            ]
675        );
676
677        let byte_vec = vec![0u8, 1]; // 2 bytes
678        let bytes = to_bytes(&byte_vec).unwrap();
679
680        #[rustfmt::skip]
681        let mut expected = vec![
682            Amf0Marker::StrictArray as u8,
683            0, 0, 0, 2, // array length
684            Amf0Marker::Number as u8,
685        ];
686        expected.extend(&0.0f64.to_be_bytes());
687        expected.push(Amf0Marker::Number as u8);
688        expected.extend(&1.0f64.to_be_bytes());
689        assert_eq!(bytes, expected);
690
691        let bytes = to_bytes(&("a", false, true)).unwrap();
692        #[rustfmt::skip]
693        assert_eq!(
694            bytes,
695            [
696                Amf0Marker::StrictArray as u8,
697                0, 0, 0, 3, // array length
698                Amf0Marker::String as u8,
699                0, 1, // length
700                b'a',
701                Amf0Marker::Boolean as u8,
702                0,
703                Amf0Marker::Boolean as u8,
704                1,
705            ]
706        );
707    }
708
709    fn number_test<T>(one: T)
710    where
711        T: serde::Serialize,
712    {
713        let bytes = to_bytes(&one).unwrap();
714        let mut expected = vec![Amf0Marker::Number as u8];
715        expected.extend(&1.0f64.to_be_bytes());
716        assert_eq!(bytes, expected);
717    }
718
719    #[test]
720    fn numbers() {
721        number_test(1u8);
722        number_test(1u16);
723        number_test(1u32);
724        number_test(1u64);
725        number_test(1i8);
726        number_test(1i16);
727        number_test(1i32);
728        number_test(1i64);
729        number_test(1.0f32);
730        number_test(1.0f64);
731    }
732
733    #[test]
734    fn simple_struct() {
735        #[derive(serde::Serialize)]
736        struct Test {
737            a: f64,
738            b: String,
739        }
740
741        let value = Test {
742            a: 1.0,
743            b: "hello".to_string(),
744        };
745
746        let bytes = to_bytes(&value).unwrap();
747
748        #[rustfmt::skip]
749        let mut expected = vec![
750            Amf0Marker::Object as u8,
751            0, 1, // length
752            b'a',
753            Amf0Marker::Number as u8,
754        ];
755        expected.extend(&1.0f64.to_be_bytes());
756        #[rustfmt::skip]
757        expected.extend_from_slice(&[
758            0, 1, // length
759            b'b',
760            Amf0Marker::String as u8,
761            0, 5, // length
762            b'h', b'e', b'l', b'l', b'o',
763            0, 0, Amf0Marker::ObjectEnd as u8,
764        ]);
765        assert_eq!(bytes, expected);
766    }
767
768    #[test]
769    fn simple_enum() {
770        #[derive(serde::Serialize)]
771        enum Test {
772            A,
773            B,
774        }
775
776        let value = Test::A;
777        let bytes = to_bytes(&value).unwrap();
778
779        #[rustfmt::skip]
780        let expected = vec![
781            Amf0Marker::String as u8,
782            0, 1, // length
783            b'A',
784        ];
785        assert_eq!(bytes, expected);
786
787        let value = Test::B;
788        let bytes = to_bytes(&value).unwrap();
789
790        #[rustfmt::skip]
791        let expected = vec![
792            Amf0Marker::String as u8,
793            0, 1, // length
794            b'B',
795        ];
796        assert_eq!(bytes, expected);
797    }
798
799    #[test]
800    fn complex_enum() {
801        #[derive(serde::Serialize)]
802        enum Test {
803            A(bool),
804            B { a: String, b: String },
805            C(bool, String),
806        }
807
808        let value = Test::A(true);
809        let bytes = to_bytes(&value).unwrap();
810        #[rustfmt::skip]
811        let expected = vec![
812            Amf0Marker::String as u8,
813            0, 1, // length
814            b'A',
815            Amf0Marker::Boolean as u8,
816            1,
817        ];
818        assert_eq!(bytes, expected);
819
820        let value = Test::B {
821            a: "hello".to_string(),
822            b: "world".to_string(),
823        };
824        let bytes = to_bytes(&value).unwrap();
825        #[rustfmt::skip]
826        let expected = vec![
827            Amf0Marker::String as u8,
828            0, 1, // length
829            b'B',
830            Amf0Marker::Object as u8,
831            0, 1, // length
832            b'a',
833            Amf0Marker::String as u8,
834            0, 5, // length
835            b'h', b'e', b'l', b'l', b'o',
836            0, 1, // length
837            b'b',
838            Amf0Marker::String as u8,
839            0, 5, // length
840            b'w', b'o', b'r', b'l', b'd',
841            0, 0, Amf0Marker::ObjectEnd as u8,
842        ];
843        assert_eq!(bytes, expected);
844
845        let value = Test::C(true, "hello".to_string());
846        let bytes = to_bytes(&value).unwrap();
847        #[rustfmt::skip]
848        let expected = vec![
849            Amf0Marker::String as u8,
850            0, 1, // length
851            b'C',
852            Amf0Marker::StrictArray as u8,
853            0, 0, 0, 2, // array length
854            Amf0Marker::Boolean as u8,
855            1,
856            Amf0Marker::String as u8,
857            0, 5, // length
858            b'h', b'e', b'l', b'l', b'o',
859        ];
860        assert_eq!(bytes, expected);
861    }
862
863    fn test_invalid_map_key<T>(key: T)
864    where
865        T: Eq + Hash + serde::Serialize,
866    {
867        let mut map = HashMap::new();
868        map.insert(key, Amf0Value::Number(1.0));
869        let err = to_bytes(&map).unwrap_err();
870        assert!(matches!(err, Amf0Error::MapKeyNotString));
871    }
872
873    #[test]
874    fn invalid_map_keys() {
875        test_invalid_map_key(false);
876
877        test_invalid_map_key(1u8);
878        test_invalid_map_key(1u16);
879        test_invalid_map_key(1u32);
880        test_invalid_map_key(1u64);
881
882        test_invalid_map_key(1i8);
883        test_invalid_map_key(1i16);
884        test_invalid_map_key(1i32);
885        test_invalid_map_key(1i64);
886
887        test_invalid_map_key('a');
888
889        test_invalid_map_key([1u8, 2, 3]);
890
891        test_invalid_map_key(None::<String>);
892        test_invalid_map_key(Some("hello"));
893        test_invalid_map_key(());
894
895        test_invalid_map_key(vec![1, 2, 3]);
896        test_invalid_map_key((1, 2, 3));
897
898        #[derive(serde::Serialize, Eq, PartialEq, Hash)]
899        struct Tuple(String, String);
900        test_invalid_map_key(Tuple("hello".to_string(), "world".to_string()));
901
902        #[derive(serde::Serialize, Eq, PartialEq, Hash)]
903        struct Struct {
904            a: String,
905        }
906        test_invalid_map_key(Struct { a: "hello".to_string() });
907
908        #[derive(serde::Serialize, Eq, PartialEq, Hash)]
909        struct Unit;
910        test_invalid_map_key(Unit);
911
912        #[derive(serde::Serialize, Eq, PartialEq, Hash)]
913        struct Newtype(String);
914        test_invalid_map_key(Newtype("hello".to_string()));
915
916        #[derive(serde::Serialize, Eq, PartialEq, Hash)]
917        enum Enum {
918            A,
919            B(bool),
920            C(String, String),
921            D { a: String },
922        }
923        test_invalid_map_key(Enum::A);
924        test_invalid_map_key(Enum::B(true));
925        test_invalid_map_key(Enum::C("hello".to_string(), "world".to_string()));
926        test_invalid_map_key(Enum::D { a: "hello".to_string() });
927    }
928}