use crate::value::Value;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NodeId(pub u64);
pub trait AstAdapter {
fn root(&self) -> NodeId;
fn children(&self, node: NodeId) -> Vec<NodeId>;
fn name(&self, node: NodeId) -> Option<String>;
fn parent(&self, _node: NodeId) -> Option<NodeId> {
None
}
fn traits(&self, _node: NodeId) -> Vec<String> {
Vec::new()
}
fn property(&self, _node: NodeId, _name: &str) -> Option<Value> {
None
}
fn children_named(&self, node: NodeId, name: &str) -> Vec<NodeId> {
self.children(node)
.into_iter()
.filter(|&c| self.name(c).as_deref() == Some(name))
.collect()
}
fn default_value(&self, _node: NodeId) -> Option<Value> {
None
}
fn metadata(&self, _node: NodeId, _key: &str) -> Option<Value> {
None
}
fn links(&self, _node: NodeId) -> Vec<(String, NodeId)> {
Vec::new()
}
fn backlinks(&self, _node: NodeId) -> Vec<(String, NodeId)> {
Vec::new()
}
fn resolve(&self, _node: NodeId, _property: &str, _hint: Option<&str>) -> Option<NodeId> {
None
}
fn link_property(
&self,
_source: NodeId,
_label: &str,
_target: NodeId,
_name: &str,
) -> Option<Value> {
None
}
fn quantifier_bound(&self) -> usize {
32
}
fn allow_shell(&self) -> bool {
false
}
fn invocation_instant(&self) -> Option<(i64, u32)> {
None
}
fn unit_scale(&self, expr: &str) -> Option<(f64, String)> {
crate::quantity::scale_expr(expr)
}
}
pub struct QuantifierBound<'a, A: AstAdapter> {
pub inner: &'a A,
pub bound: usize,
}
impl<A: AstAdapter> AstAdapter for QuantifierBound<'_, A> {
fn root(&self) -> NodeId {
self.inner.root()
}
fn children(&self, node: NodeId) -> Vec<NodeId> {
self.inner.children(node)
}
fn name(&self, node: NodeId) -> Option<String> {
self.inner.name(node)
}
fn parent(&self, node: NodeId) -> Option<NodeId> {
self.inner.parent(node)
}
fn traits(&self, node: NodeId) -> Vec<String> {
self.inner.traits(node)
}
fn property(&self, node: NodeId, name: &str) -> Option<Value> {
self.inner.property(node, name)
}
fn children_named(&self, node: NodeId, name: &str) -> Vec<NodeId> {
self.inner.children_named(node, name)
}
fn default_value(&self, node: NodeId) -> Option<Value> {
self.inner.default_value(node)
}
fn metadata(&self, node: NodeId, key: &str) -> Option<Value> {
self.inner.metadata(node, key)
}
fn links(&self, node: NodeId) -> Vec<(String, NodeId)> {
self.inner.links(node)
}
fn backlinks(&self, node: NodeId) -> Vec<(String, NodeId)> {
self.inner.backlinks(node)
}
fn resolve(&self, node: NodeId, property: &str, hint: Option<&str>) -> Option<NodeId> {
self.inner.resolve(node, property, hint)
}
fn link_property(
&self,
source: NodeId,
label: &str,
target: NodeId,
name: &str,
) -> Option<Value> {
self.inner.link_property(source, label, target, name)
}
fn quantifier_bound(&self) -> usize {
self.bound
}
fn allow_shell(&self) -> bool {
self.inner.allow_shell()
}
fn invocation_instant(&self) -> Option<(i64, u32)> {
self.inner.invocation_instant()
}
fn unit_scale(&self, expr: &str) -> Option<(f64, String)> {
self.inner.unit_scale(expr)
}
}
pub struct AllowShell<'a, A: AstAdapter> {
pub inner: &'a A,
}
impl<A: AstAdapter> AstAdapter for AllowShell<'_, A> {
fn root(&self) -> NodeId {
self.inner.root()
}
fn children(&self, node: NodeId) -> Vec<NodeId> {
self.inner.children(node)
}
fn name(&self, node: NodeId) -> Option<String> {
self.inner.name(node)
}
fn parent(&self, node: NodeId) -> Option<NodeId> {
self.inner.parent(node)
}
fn traits(&self, node: NodeId) -> Vec<String> {
self.inner.traits(node)
}
fn property(&self, node: NodeId, name: &str) -> Option<Value> {
self.inner.property(node, name)
}
fn children_named(&self, node: NodeId, name: &str) -> Vec<NodeId> {
self.inner.children_named(node, name)
}
fn default_value(&self, node: NodeId) -> Option<Value> {
self.inner.default_value(node)
}
fn metadata(&self, node: NodeId, key: &str) -> Option<Value> {
self.inner.metadata(node, key)
}
fn links(&self, node: NodeId) -> Vec<(String, NodeId)> {
self.inner.links(node)
}
fn backlinks(&self, node: NodeId) -> Vec<(String, NodeId)> {
self.inner.backlinks(node)
}
fn resolve(&self, node: NodeId, property: &str, hint: Option<&str>) -> Option<NodeId> {
self.inner.resolve(node, property, hint)
}
fn link_property(
&self,
source: NodeId,
label: &str,
target: NodeId,
name: &str,
) -> Option<Value> {
self.inner.link_property(source, label, target, name)
}
fn quantifier_bound(&self) -> usize {
self.inner.quantifier_bound()
}
fn allow_shell(&self) -> bool {
true
}
fn invocation_instant(&self) -> Option<(i64, u32)> {
self.inner.invocation_instant()
}
fn unit_scale(&self, expr: &str) -> Option<(f64, String)> {
self.inner.unit_scale(expr)
}
}
pub struct WithNow<'a, A: AstAdapter> {
pub inner: &'a A,
pub secs: i64,
pub nanos: u32,
}
impl<A: AstAdapter> AstAdapter for WithNow<'_, A> {
fn root(&self) -> NodeId {
self.inner.root()
}
fn children(&self, node: NodeId) -> Vec<NodeId> {
self.inner.children(node)
}
fn name(&self, node: NodeId) -> Option<String> {
self.inner.name(node)
}
fn parent(&self, node: NodeId) -> Option<NodeId> {
self.inner.parent(node)
}
fn traits(&self, node: NodeId) -> Vec<String> {
self.inner.traits(node)
}
fn property(&self, node: NodeId, name: &str) -> Option<Value> {
self.inner.property(node, name)
}
fn children_named(&self, node: NodeId, name: &str) -> Vec<NodeId> {
self.inner.children_named(node, name)
}
fn default_value(&self, node: NodeId) -> Option<Value> {
self.inner.default_value(node)
}
fn metadata(&self, node: NodeId, key: &str) -> Option<Value> {
self.inner.metadata(node, key)
}
fn links(&self, node: NodeId) -> Vec<(String, NodeId)> {
self.inner.links(node)
}
fn backlinks(&self, node: NodeId) -> Vec<(String, NodeId)> {
self.inner.backlinks(node)
}
fn resolve(&self, node: NodeId, property: &str, hint: Option<&str>) -> Option<NodeId> {
self.inner.resolve(node, property, hint)
}
fn link_property(
&self,
source: NodeId,
label: &str,
target: NodeId,
name: &str,
) -> Option<Value> {
self.inner.link_property(source, label, target, name)
}
fn quantifier_bound(&self) -> usize {
self.inner.quantifier_bound()
}
fn allow_shell(&self) -> bool {
self.inner.allow_shell()
}
fn invocation_instant(&self) -> Option<(i64, u32)> {
Some((self.secs, self.nanos))
}
fn unit_scale(&self, expr: &str) -> Option<(f64, String)> {
self.inner.unit_scale(expr)
}
}