pub(crate) mod de;
mod from;
mod ser;
use std::fmt;
use serde::{de::DeserializeOwned, ser::Serialize};
use self::{de::ValueDeserializer, ser::ValueSerializer};
use crate::{format, Number, Result};
pub type Map<K, V> = indexmap::IndexMap<K, V>;
#[derive(Debug, PartialEq, Eq, Clone, Default)]
pub enum Value {
#[default]
Null,
Bool(bool),
Number(Number),
String(String),
Array(Vec<Value>),
Object(Map<String, Value>),
}
impl Value {
pub fn as_array(&self) -> Option<&Vec<Value>> {
match self {
Self::Array(array) => Some(array),
_ => None,
}
}
pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
match self {
Self::Array(array) => Some(array),
_ => None,
}
}
pub fn as_bool(&self) -> Option<bool> {
match *self {
Self::Bool(b) => Some(b),
_ => None,
}
}
pub fn as_f64(&self) -> Option<f64> {
self.as_number().and_then(Number::as_f64)
}
pub fn as_i64(&self) -> Option<i64> {
self.as_number().and_then(Number::as_i64)
}
pub fn as_null(&self) -> Option<()> {
match self {
Self::Null => Some(()),
_ => None,
}
}
pub fn as_number(&self) -> Option<&Number> {
match self {
Self::Number(num) => Some(num),
_ => None,
}
}
pub fn as_object(&self) -> Option<&Map<String, Value>> {
match self {
Self::Object(object) => Some(object),
_ => None,
}
}
pub fn as_object_mut(&mut self) -> Option<&mut Map<String, Value>> {
match self {
Self::Object(object) => Some(object),
_ => None,
}
}
pub fn as_str(&self) -> Option<&str> {
match self {
Self::String(s) => Some(s),
_ => None,
}
}
pub fn as_u64(&self) -> Option<u64> {
self.as_number().and_then(Number::as_u64)
}
pub fn is_array(&self) -> bool {
self.as_array().is_some()
}
pub fn is_boolean(&self) -> bool {
self.as_bool().is_some()
}
pub fn is_f64(&self) -> bool {
self.as_number().is_some_and(Number::is_f64)
}
pub fn is_i64(&self) -> bool {
self.as_number().is_some_and(Number::is_i64)
}
pub fn is_number(&self) -> bool {
self.as_number().is_some()
}
pub fn is_null(&self) -> bool {
self.as_null().is_some()
}
pub fn is_object(&self) -> bool {
self.as_object().is_some()
}
pub fn is_string(&self) -> bool {
self.as_str().is_some()
}
pub fn is_u64(&self) -> bool {
self.as_number().is_some_and(Number::is_u64)
}
pub fn take(&mut self) -> Value {
std::mem::replace(self, Value::Null)
}
}
impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let formatted = format::to_string(self).expect("a Value failed to format unexpectedly");
f.write_str(&formatted)
}
}
pub fn to_value<T>(value: T) -> Result<Value>
where
T: Serialize,
{
value.serialize(ValueSerializer)
}
pub fn from_value<T>(value: Value) -> Result<T>
where
T: DeserializeOwned,
{
T::deserialize(ValueDeserializer::new(value))
}