1use std::io;
4
5use byteorder::{BigEndian, WriteBytesExt};
6
7use crate::{Amf0Array, Amf0Error, Amf0Marker, Amf0Object};
8
9#[derive(Debug)]
13pub struct Amf0Encoder<W> {
14 writer: W,
15}
16
17impl<W> Amf0Encoder<W> {
18 pub fn new(writer: W) -> Self {
20 Amf0Encoder { writer }
21 }
22}
23
24impl<W> Amf0Encoder<W>
25where
26 W: io::Write,
27{
28 pub fn encode_boolean(&mut self, value: bool) -> Result<(), Amf0Error> {
30 self.writer.write_u8(Amf0Marker::Boolean as u8)?;
31 self.writer.write_u8(value as u8)?;
32 Ok(())
33 }
34
35 pub fn encode_number(&mut self, value: f64) -> Result<(), Amf0Error> {
37 self.writer.write_u8(Amf0Marker::Number as u8)?;
38 self.writer.write_f64::<BigEndian>(value)?;
39 Ok(())
40 }
41
42 pub fn encode_string(&mut self, value: &str) -> Result<(), Amf0Error> {
46 let len = value.len();
47
48 if len <= (u16::MAX as usize) {
49 self.writer.write_u8(Amf0Marker::String as u8)?;
51 self.writer.write_u16::<BigEndian>(len as u16)?;
52 self.writer.write_all(value.as_bytes())?;
53 } else {
54 let len: u32 = len.try_into()?;
58
59 self.writer.write_u8(Amf0Marker::LongString as u8)?;
60 self.writer.write_u32::<BigEndian>(len)?;
61 self.writer.write_all(value.as_bytes())?;
62 }
63
64 Ok(())
65 }
66
67 pub fn encode_null(&mut self) -> Result<(), Amf0Error> {
69 self.writer.write_u8(Amf0Marker::Null as u8)?;
70 Ok(())
71 }
72
73 pub fn encode_undefined(&mut self) -> Result<(), Amf0Error> {
75 self.writer.write_u8(Amf0Marker::Undefined as u8)?;
76 Ok(())
77 }
78
79 pub(crate) fn encode_array_header(&mut self, len: u32) -> Result<(), Amf0Error> {
80 self.writer.write_u8(Amf0Marker::StrictArray as u8)?;
81 self.writer.write_u32::<BigEndian>(len)?;
82 Ok(())
83 }
84
85 pub fn encode_array(&mut self, values: &Amf0Array) -> Result<(), Amf0Error> {
87 self.encode_array_header(values.len().try_into()?)?;
88
89 for value in values.iter() {
90 value.encode(self)?;
91 }
92
93 Ok(())
94 }
95
96 pub(crate) fn encode_object_header(&mut self) -> Result<(), Amf0Error> {
97 self.writer.write_u8(Amf0Marker::Object as u8)?;
98 Ok(())
99 }
100
101 pub(crate) fn encode_object_key(&mut self, key: &str) -> Result<(), Amf0Error> {
102 self.writer.write_u16::<BigEndian>(key.len().try_into()?)?;
103 self.writer.write_all(key.as_bytes())?;
104 Ok(())
105 }
106
107 pub(crate) fn encode_object_trailer(&mut self) -> Result<(), Amf0Error> {
108 self.writer.write_u24::<BigEndian>(Amf0Marker::ObjectEnd as u32)?;
109 Ok(())
110 }
111
112 pub fn encode_object(&mut self, values: &Amf0Object) -> Result<(), Amf0Error> {
114 self.encode_object_header()?;
115
116 for (key, value) in values.iter() {
117 self.encode_object_key(key.as_str())?;
118 value.encode(self)?;
119 }
120
121 self.encode_object_trailer()?;
122
123 Ok(())
124 }
125
126 #[cfg(feature = "serde")]
128 pub fn serialize<T>(&mut self, value: T) -> Result<(), Amf0Error>
129 where
130 T: serde::Serialize,
131 {
132 value.serialize(self)?;
133 Ok(())
134 }
135}