1use cookie_factory::lib::std::fmt::Formatter;
2use core::fmt;
3use derive_try_from_primitive::TryFromPrimitive;
4use enumset::EnumSet;
5use enumset::EnumSetType;
6use nom::lib::std::iter::FromIterator;
7use std::ops::Deref;
8use std::rc::Rc;
9
10#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12#[derive(Debug, PartialEq)]
13pub struct Lso {
14    pub header: Header,
16    pub body: Vec<Element>,
18}
19
20impl Lso {
21    #[inline]
23    pub fn new_empty(name: impl Into<String>, version: AMFVersion) -> Self {
24        Self::new(Vec::new(), name, version)
25    }
26
27    #[inline]
29    pub fn new(body: Vec<Element>, name: impl Into<String>, version: AMFVersion) -> Self {
30        Self {
31            header: Header::new(name, version),
32            body,
33        }
34    }
35}
36
37impl IntoIterator for Lso {
38    type Item = Element;
39    type IntoIter = std::vec::IntoIter<Self::Item>;
40
41    fn into_iter(self) -> Self::IntoIter {
42        self.body.into_iter()
43    }
44}
45
46#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
48#[derive(TryFromPrimitive, Eq, PartialEq, Debug, Copy, Clone)]
49#[repr(u8)]
50pub enum AMFVersion {
51    AMF0 = 0,
53    AMF3 = 3,
55}
56
57impl fmt::Display for AMFVersion {
58    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
59        match self {
60            AMFVersion::AMF0 => f.write_str("AMF0"),
61            AMFVersion::AMF3 => f.write_str("AMF3"),
62        }
63    }
64}
65
66#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
68#[derive(Debug, PartialEq)]
69pub struct Header {
70    pub length: u32,
72    pub name: String,
74    pub format_version: AMFVersion,
76}
77
78impl Header {
79    #[inline]
81    pub fn new(name: impl Into<String>, version: AMFVersion) -> Self {
82        Self {
83            length: 0,
84            name: name.into(),
85            format_version: version,
86        }
87    }
88}
89
90#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
92#[derive(Clone, Debug, PartialEq)]
93pub struct Element {
94    pub name: String,
96    pub value: Rc<Value>,
98}
99
100impl Element {
101    #[inline]
103    pub fn new(name: impl Into<String>, value: impl Into<Value>) -> Self {
104        Self {
105            name: name.into(),
106            value: Rc::new(value.into()),
107        }
108    }
109
110    pub fn value(&self) -> &Value {
112        self.value.deref()
113    }
114
115    pub fn name(&self) -> &str {
117        self.name.as_str()
118    }
119}
120
121#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
124#[derive(Debug, Clone, PartialEq)]
125pub enum Value {
126    Number(f64),
128    Bool(bool),
130    String(String),
132    Object(Vec<Element>, Option<ClassDefinition>),
134    Null,
136    Undefined,
138    ECMAArray(Vec<Rc<Value>>, Vec<Element>, u32),
141    StrictArray(Vec<Rc<Value>>),
143    Date(f64, Option<u16>),
145    Unsupported,
147    XML(String, bool),
149    AMF3(Rc<Value>),
151    Integer(i32),
154    ByteArray(Vec<u8>),
156    VectorInt(Vec<i32>, bool),
159    VectorUInt(Vec<u32>, bool),
162    VectorDouble(Vec<f64>, bool),
165    VectorObject(Vec<Rc<Value>>, String, bool),
168    Dictionary(Vec<(Rc<Value>, Rc<Value>)>, bool),
171    Custom(Vec<Element>, Vec<Element>, Option<ClassDefinition>),
174}
175
176impl FromIterator<Value> for Vec<Rc<Value>> {
177    fn from_iter<T: IntoIterator<Item = Value>>(iter: T) -> Self {
178        iter.into_iter().map(Rc::new).collect()
179    }
180}
181
182#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
184#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
185pub struct ClassDefinition {
186    pub name: String,
188    pub attributes: EnumSet<Attribute>,
190    pub static_properties: Vec<String>,
192}
193
194impl Default for ClassDefinition {
195    fn default() -> Self {
196        Self {
197            name: "Object".to_string(),
198            attributes: EnumSet::empty(),
199            static_properties: Vec::new(),
200        }
201    }
202}
203
204impl ClassDefinition {
205    pub fn default_with_name(name: String) -> Self {
207        Self {
208            name,
209            attributes: EnumSet::empty(),
210            static_properties: Vec::new(),
211        }
212    }
213}
214
215#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
217#[derive(EnumSetType, Debug)]
218pub enum Attribute {
219    Dynamic,
221    External,
223}