use std::sync::Arc;
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
Null,
Derived,
Bool(bool),
LogicalUnknown,
Integer(i64),
Real(f64),
Text(Arc<str>),
Binary(Arc<str>),
Enum(Arc<str>),
Ref(EntityId),
List(Vec<Value>),
Typed {
type_name: Arc<str>,
value: Box<Value>,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct EntityId(pub u64);
impl std::fmt::Display for EntityId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "#{}", self.0)
}
}
impl Value {
pub fn as_ref_id(&self) -> Option<EntityId> {
match self {
Value::Ref(id) => Some(*id),
_ => None,
}
}
pub fn as_bool(&self) -> Option<bool> {
match self {
Value::Bool(b) => Some(*b),
_ => None,
}
}
pub fn as_i64(&self) -> Option<i64> {
match self {
Value::Integer(i) => Some(*i),
_ => None,
}
}
pub fn as_text(&self) -> Option<&str> {
match self {
Value::Text(s) => Some(s),
_ => None,
}
}
pub fn as_f64(&self) -> Option<f64> {
match self {
Value::Real(r) => Some(*r),
Value::Integer(i) => Some(*i as f64),
_ => None,
}
}
pub fn as_list(&self) -> Option<&[Value]> {
match self {
Value::List(items) => Some(items),
_ => None,
}
}
pub fn unwrap_typed(&self) -> &Value {
match self {
Value::Typed { value, .. } => value.unwrap_typed(),
other => other,
}
}
pub fn for_each_ref(&self, f: &mut impl FnMut(EntityId)) {
match self {
Value::Ref(id) => f(*id),
Value::List(items) => items.iter().for_each(|v| v.for_each_ref(f)),
Value::Typed { value, .. } => value.for_each_ref(f),
_ => {}
}
}
}