Skip to main content

oak_json/language/
value.rs

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