use std::collections::BTreeMap;
use std::sync::Arc;
use crate::dim::Dimension;
use crate::diag::{Diag, Diagnostic, ErrorCode, Span};
use crate::eval::value::EquationProvenance;
use crate::packs::contract::ArgContract;
use crate::parser::Expr;
use crate::quantity::UnitExpr;
#[derive(Debug, Clone)]
pub struct EquationRecord {
pub path_key: String,
pub namespace: String,
pub id: String,
pub body: Arc<Expr>,
pub result_unit: UnitExpr,
pub result_dim: Dimension,
pub args: BTreeMap<String, ArgContract>,
pub provenance: EquationProvenance,
}
#[derive(Debug, Clone, Default)]
pub struct EquationRegistry {
by_path: Arc<BTreeMap<String, Arc<EquationRecord>>>,
}
impl EquationRegistry {
pub fn empty() -> Self {
Self::default()
}
pub(crate) fn from_map(map: BTreeMap<String, Arc<EquationRecord>>) -> Self {
Self {
by_path: Arc::new(map),
}
}
pub fn lookup(&self, path: &[String]) -> Option<&Arc<EquationRecord>> {
let key = path.join(".");
self.by_path.get(&key)
}
pub fn equations(&self) -> impl Iterator<Item = &Arc<EquationRecord>> {
self.by_path.values()
}
pub(crate) fn insert(
map: &mut BTreeMap<String, Arc<EquationRecord>>,
record: Arc<EquationRecord>,
) -> Result<(), Diag> {
if map.contains_key(&record.path_key) {
return Err(Diag::new(Diagnostic::error(
ErrorCode::PackParse,
format!("duplicate equation `{}`", record.path_key),
Span::empty(0),
)));
}
map.insert(record.path_key.clone(), record);
Ok(())
}
}