use crate::value::*;
use microcad_lang_base::Identifier;
pub trait ValueAccess {
fn by_id(&self, id: &Identifier) -> Option<&Value>;
fn by_ty(&self, ty: &Type) -> Option<&Value>;
fn by_str<'a, T>(&'a self, id: &str) -> ValueResult<T>
where
T: std::convert::TryFrom<&'a Value>,
T::Error: std::fmt::Debug,
{
let id = &Identifier::no_ref(id);
if let Some(val) = self.by_id(id) {
if let Ok(val) = TryInto::try_into(val) {
Ok(val)
} else {
Err(ValueError::CannotConvert(
val.to_string(),
std::any::type_name::<T>().into(),
))
}
} else {
Err(ValueError::IdNotFound(id.clone()))
}
}
fn get<'a, T>(&'a self, id: &str) -> T
where
T: std::convert::TryFrom<&'a Value>,
T::Error: std::fmt::Debug,
{
self.by_str(id).expect("No error")
}
fn get_value(&self, id: &str) -> ValueResult<&Value> {
let id = Identifier::no_ref(id);
if let Some(value) = self.by_id(&id) {
Ok(value)
} else {
Err(ValueError::IdNotFound(id))
}
}
fn contains_id(&self, id: &Identifier) -> bool {
self.by_id(id).is_some()
}
}