use alloc::string::String;
use alloc::vec::Vec;
use crate::number::JsonNumber;
#[derive(Debug, Clone, PartialEq)]
pub enum JsonValue {
Null,
Bool(bool),
Number(JsonNumber),
String(String),
Array(Vec<JsonValue>),
Object(JsonObject),
}
impl JsonValue {
pub fn array<I: IntoIterator<Item = JsonValue>>(items: I) -> Self {
JsonValue::Array(items.into_iter().collect())
}
pub fn is_null(&self) -> bool {
matches!(self, JsonValue::Null)
}
pub fn as_bool(&self) -> Option<bool> {
match self {
JsonValue::Bool(b) => Some(*b),
_ => None,
}
}
pub fn as_number(&self) -> Option<&JsonNumber> {
match self {
JsonValue::Number(n) => Some(n),
_ => None,
}
}
pub fn as_str(&self) -> Option<&str> {
match self {
JsonValue::String(s) => Some(s),
_ => None,
}
}
pub fn as_array(&self) -> Option<&[JsonValue]> {
match self {
JsonValue::Array(a) => Some(a),
_ => None,
}
}
pub fn as_object(&self) -> Option<&JsonObject> {
match self {
JsonValue::Object(o) => Some(o),
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct JsonMember {
key: String,
value: JsonValue,
}
impl JsonMember {
pub fn key(&self) -> &str {
&self.key
}
pub fn value(&self) -> &JsonValue {
&self.value
}
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct JsonObject {
entries: Vec<JsonMember>,
}
impl JsonObject {
pub fn new() -> Self {
Self {
entries: Vec::new(),
}
}
pub(crate) fn push_unique(&mut self, key: String, value: JsonValue) {
self.entries.push(JsonMember { key, value });
}
pub fn get(&self, key: &str) -> Option<&JsonValue> {
self.entries.iter().find(|m| m.key == key).map(|m| &m.value)
}
pub fn contains_key(&self, key: &str) -> bool {
self.entries.iter().any(|m| m.key == key)
}
pub fn insert(&mut self, key: String, value: JsonValue) -> Option<JsonValue> {
if let Some(member) = self.entries.iter_mut().find(|m| m.key == key) {
Some(core::mem::replace(&mut member.value, value))
} else {
self.entries.push(JsonMember { key, value });
None
}
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
pub fn iter(&self) -> core::slice::Iter<'_, JsonMember> {
self.entries.iter()
}
}