Skip to main content

oak_xml/language/
value.rs

1#[cfg(feature = "serde")]
2use serde::Deserialize;
3use std::collections::HashMap;
4
5/// XML value representation.
6///
7/// This represents the pure value of an XML element without any source code location information.
8#[derive(Debug, Clone, PartialEq)]
9#[cfg_attr(feature = "serde", derive(Deserialize))]
10pub enum XmlValue {
11    /// String value.
12    String(String),
13    /// Integer value.
14    Integer(i64),
15    /// Floating-point value.
16    Float(f64),
17    /// Boolean value.
18    Boolean(bool),
19    /// Null value.
20    Null,
21    /// Array value.
22    Array(XmlArray),
23    /// Object value.
24    Object(XmlObject),
25}
26
27/// Array wrapper of XML
28#[derive(Debug, Clone, PartialEq)]
29#[cfg_attr(feature = "serde", derive(Deserialize))]
30pub struct XmlArray {
31    pub list: Vec<XmlValue>,
32}
33
34/// Object wrapper of XML
35#[derive(Debug, Clone, PartialEq)]
36#[cfg_attr(feature = "serde", derive(Deserialize))]
37pub struct XmlObject {
38    pub dict: HashMap<String, XmlValue>,
39}
40
41impl XmlValue {
42    /// Returns the string slice if the value is a string.
43    pub fn as_str(&self) -> Option<&str> {
44        match self {
45            XmlValue::String(s) => Some(s),
46            _ => None,
47        }
48    }
49
50    /// Returns the integer value if the value is an integer.
51    pub fn as_integer(&self) -> Option<i64> {
52        match self {
53            XmlValue::Integer(i) => Some(*i),
54            _ => None,
55        }
56    }
57
58    /// Returns the floating-point value if the value is a float.
59    pub fn as_float(&self) -> Option<f64> {
60        match self {
61            XmlValue::Float(f) => Some(*f),
62            _ => None,
63        }
64    }
65
66    /// Returns the boolean value if the value is a boolean.
67    pub fn as_bool(&self) -> Option<bool> {
68        match self {
69            XmlValue::Boolean(b) => Some(*b),
70            _ => None,
71        }
72    }
73
74    /// Returns true if the value is null.
75    pub fn is_null(&self) -> bool {
76        matches!(self, XmlValue::Null)
77    }
78
79    /// Returns a reference to the array if the value is an array.
80    pub fn as_array(&self) -> Option<&Vec<XmlValue>> {
81        match self {
82            XmlValue::Array(XmlArray { list: a }) => Some(a),
83            _ => None,
84        }
85    }
86
87    /// Returns a reference to the object if the value is an object.
88    pub fn as_object(&self) -> Option<&HashMap<String, XmlValue>> {
89        match self {
90            XmlValue::Object(XmlObject { dict: o }) => Some(o),
91            _ => None,
92        }
93    }
94
95    /// Gets a value from the object by key name.
96    pub fn get(&self, key: &str) -> Option<&XmlValue> {
97        match self {
98            XmlValue::Object(XmlObject { dict: o }) => o.get(key),
99            _ => None,
100        }
101    }
102}
103
104impl std::fmt::Display for XmlValue {
105    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106        match self {
107            XmlValue::String(s) => write!(f, "\"{}\"", s),
108            XmlValue::Integer(i) => write!(f, "{}", i),
109            XmlValue::Float(fl) => write!(f, "{}", fl),
110            XmlValue::Boolean(b) => write!(f, "{}", b),
111            XmlValue::Null => write!(f, "null"),
112            XmlValue::Array(XmlArray { list: a }) => {
113                write!(f, "[")?;
114                for (i, item) in a.iter().enumerate() {
115                    if i > 0 {
116                        write!(f, ", ")?;
117                    }
118                    write!(f, "{}", item)?;
119                }
120                write!(f, "]")
121            }
122            XmlValue::Object(XmlObject { dict: o }) => {
123                write!(f, "{{")?;
124                for (i, (key, value)) in o.iter().enumerate() {
125                    if i > 0 {
126                        write!(f, ", ")?;
127                    }
128                    write!(f, "\"{}\": {}", key, value)?;
129                }
130                write!(f, "}}")
131            }
132        }
133    }
134}