use crate::values::*;
use crate::Error;
use crate::ValueType;
use std::collections::HashMap;
#[derive(Debug, Default)]
pub struct VariableRegistry {
entries: HashMap<String, VariableDeclOrConstant>,
}
impl VariableRegistry {
pub fn new() -> Self {
Self {
entries: HashMap::new(),
}
}
pub fn define_constant<T>(
&mut self,
name: impl Into<String>,
value: T,
) -> Result<&mut Self, Error>
where
T: IntoConstant,
{
self.entries
.insert(name.into(), VariableDeclOrConstant::new_constant(value));
Ok(self)
}
pub fn declare<T>(&mut self, name: impl Into<String>) -> Result<&mut Self, Error>
where
T: TypedValue,
{
self.entries
.insert(name.into(), VariableDeclOrConstant::new(T::value_type()));
Ok(self)
}
pub fn declare_with_type(
&mut self,
name: impl Into<String>,
value_type: ValueType,
) -> Result<&mut Self, Error> {
self.entries
.insert(name.into(), VariableDeclOrConstant::new(value_type));
Ok(self)
}
pub fn entries(&self) -> impl Iterator<Item = (&String, &VariableDeclOrConstant)> {
self.entries.iter()
}
pub fn entries_mut(&mut self) -> impl Iterator<Item = (&String, &mut VariableDeclOrConstant)> {
self.entries.iter_mut()
}
pub fn find(&self, name: &str) -> Option<&VariableDeclOrConstant> {
self.entries.get(name)
}
pub fn find_mut(&mut self, name: &str) -> Option<&mut VariableDeclOrConstant> {
self.entries.get_mut(name)
}
pub fn remove(&mut self, name: &str) -> Option<VariableDeclOrConstant> {
self.entries.remove(name)
}
pub fn clear(&mut self) {
self.entries.clear();
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
}
#[derive(Debug)]
pub struct VariableDeclOrConstant {
r#type: ValueType,
constant: Option<Constant>,
}
impl VariableDeclOrConstant {
pub fn new_constant<T>(value: T) -> Self
where
T: IntoConstant,
{
Self {
r#type: T::value_type(),
constant: Some(value.into_constant()),
}
}
pub fn new(r#type: ValueType) -> Self {
Self {
r#type,
constant: None,
}
}
pub fn is_constant(&self) -> bool {
self.constant.is_some()
}
pub fn decl(&self) -> &ValueType {
&self.r#type
}
pub fn constant(&self) -> Option<&Constant> {
self.constant.as_ref()
}
}