1use std::io::Write;
3
4use cookie_factory::bytes::be_u32;
5use cookie_factory::combinator::cond;
6use cookie_factory::combinator::slice;
7use cookie_factory::gen;
8use cookie_factory::sequence::tuple;
9use cookie_factory::SerializeFn;
10
11use crate::amf3::write::AMF3Encoder;
12use crate::nom_utils::write_string;
13use crate::types::{AMFVersion, Header, Lso};
14use crate::{FORMAT_VERSION_AMF0, FORMAT_VERSION_AMF3, HEADER_SIGNATURE, HEADER_VERSION, PADDING};
15
16#[derive(Default)]
18pub struct Writer {
19 pub amf3_encoder: AMF3Encoder,
21}
22
23impl Writer {
24 pub fn write_full<'a, 'b: 'a, W: Write + 'a>(
26 &'a mut self,
27 lso: &'b Lso,
28 ) -> impl SerializeFn<W> + 'a {
29 let amf0 = cond(
30 lso.header.format_version == AMFVersion::AMF0,
31 crate::amf0::write::write_body(&lso.body),
32 );
33 let amf3 = cond(
34 lso.header.format_version == AMFVersion::AMF3,
35 self.amf3_encoder.write_body(&lso.body),
36 );
37
38 tuple((write_header(&lso.header), amf0, amf3))
39 }
40}
41
42fn write_header<'a, 'b: 'a, W: Write + 'a>(header: &'b Header) -> impl SerializeFn<W> + 'a {
43 tuple((
44 slice(HEADER_VERSION),
45 be_u32(header.length),
46 slice(HEADER_SIGNATURE),
47 write_string(&header.name),
48 slice(PADDING),
49 slice(PADDING),
50 slice(PADDING),
51 cond(
52 header.format_version == AMFVersion::AMF0,
53 slice(&[FORMAT_VERSION_AMF0]),
54 ),
55 cond(
56 header.format_version == AMFVersion::AMF3,
57 slice(&[FORMAT_VERSION_AMF3]),
58 ),
59 ))
60}
61
62pub fn write_to_bytes(lso: &Lso) -> Vec<u8> {
64 let v = vec![];
65
66 let mut s = Writer::default();
67 let serialise = s.write_full(lso);
68 let (buffer, _size) = gen(serialise, v).unwrap();
69 buffer
70}