mod map;
mod number;
mod variant;
use eon_syntax::{FormatOptions, Result, TokenTree};
pub use self::{map::Map, number::Number, variant::Variant};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Value {
Null,
Bool(bool),
Number(Number),
String(String),
List(Vec<Value>),
Map(Map),
Variant(Variant),
}
impl Value {
pub fn new_variant(name: String, values: Vec<Self>) -> Self {
if let Ok(values) = vec1::Vec1::try_from_vec(values) {
Self::Variant(Variant { name, values })
} else {
Self::String(name)
}
}
pub fn format(&self, options: &FormatOptions) -> String {
TokenTree::from(self.clone()).format(options)
}
pub fn as_bool(&self) -> Option<bool> {
if let Self::Bool(b) = self {
Some(*b)
} else {
None
}
}
pub fn as_number(&self) -> Option<&Number> {
if let Self::Number(n) = self {
Some(n)
} else {
None
}
}
pub fn as_string(&self) -> Option<&str> {
if let Self::String(s) = self {
Some(s)
} else {
None
}
}
pub fn as_list(&self) -> Option<&[Self]> {
if let Self::List(l) = self {
Some(l)
} else {
None
}
}
pub fn as_map(&self) -> Option<&Map> {
if let Self::Map(m) = self {
Some(m)
} else {
None
}
}
pub fn as_variant(&self) -> Option<&Variant> {
if let Self::Variant(v) = self {
Some(v)
} else {
None
}
}
}
impl std::fmt::Display for Value {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.format(&crate::FormatOptions::default()).fmt(f)
}
}
impl std::str::FromStr for Value {
type Err = crate::Error;
fn from_str(eon_source: &str) -> Result<Self, Self::Err> {
TokenTree::parse_str(eon_source).and_then(|tt| Self::try_from_token_tree(eon_source, &tt))
}
}
impl From<bool> for Value {
#[inline]
fn from(value: bool) -> Self {
Self::Bool(value)
}
}
impl From<Number> for Value {
#[inline]
fn from(value: Number) -> Self {
Self::Number(value)
}
}
impl From<&str> for Value {
#[inline]
fn from(value: &str) -> Self {
Self::String(value.into())
}
}
impl From<String> for Value {
#[inline]
fn from(value: String) -> Self {
Self::String(value)
}
}
impl From<Vec<Self>> for Value {
#[inline]
fn from(value: Vec<Self>) -> Self {
Self::List(value)
}
}
impl From<Map> for Value {
#[inline]
fn from(value: Map) -> Self {
Self::Map(value)
}
}
impl From<Variant> for Value {
#[inline]
fn from(value: Variant) -> Self {
Self::Variant(value)
}
}
macro_rules! impl_value_from_number {
($t:ty) => {
impl From<$t> for Value {
#[inline]
fn from(value: $t) -> Self {
Value::Number(Number::from(value))
}
}
};
}
impl_value_from_number!(i8);
impl_value_from_number!(i16);
impl_value_from_number!(i32);
impl_value_from_number!(i64);
impl_value_from_number!(i128);
impl_value_from_number!(u8);
impl_value_from_number!(u16);
impl_value_from_number!(u32);
impl_value_from_number!(u64);
impl_value_from_number!(u128);
impl_value_from_number!(f32);
impl_value_from_number!(f64);
impl From<char> for Value {
#[inline]
fn from(value: char) -> Self {
Self::String(value.to_string())
}
}
impl From<&[u8]> for Value {
#[inline]
fn from(value: &[u8]) -> Self {
Self::List(value.iter().map(|&b| Self::from(b)).collect())
}
}