Skip to main content

lumen_engine/node/
delegate.rs

1use super::{
2    ids::NodeId,
3    property::{PropertyExpression, PropertyValue},
4    schema::PropertyDef,
5};
6
7pub struct DelegateEvalContext<'a> {
8    pub node_id: NodeId,
9    pub property_path: &'a str,
10    pub expr: &'a crate::expr::ExpressionContext<'a>,
11}
12
13impl<'a> DelegateEvalContext<'a> {
14    pub fn child(&'a self, property_path: &'a str) -> Self {
15        Self {
16            node_id: self.node_id,
17            property_path,
18            expr: self.expr,
19        }
20    }
21}
22
23pub trait DelegateEvaluable: Clone {
24    type Evaluated;
25
26    fn eval(&self, ctx: &DelegateEvalContext<'_>) -> crate::Result<Self::Evaluated>;
27}
28
29pub trait DelegateValue: DelegateEvaluable {
30    fn to_property_value(&self) -> PropertyValue;
31    fn to_property_expression(&self) -> PropertyExpression {
32        PropertyExpression::Value(self.to_property_value())
33    }
34    fn from_property_expression(value: PropertyExpression) -> crate::Result<Self>
35    where
36        Self: Sized;
37}
38
39pub trait Delegated: Clone + Default + Sized {
40    type Delegate: Clone;
41
42    fn into_delegate(self) -> Self::Delegate;
43}
44
45pub struct NodeParamEvalContext<'a> {
46    pub node_id: NodeId,
47    pub expr: &'a crate::expr::ExpressionContext<'a>,
48}
49
50pub trait NodeParams: Clone + Default {
51    type Evaluated;
52
53    fn property_defs() -> Vec<PropertyDef>;
54    fn is_property(id: &str) -> bool;
55    fn default_properties(&self) -> Vec<(&'static str, PropertyValue)>;
56    fn get_property(&self, id: &str) -> Option<PropertyExpression>;
57    fn eval(&self, ctx: &NodeParamEvalContext<'_>) -> crate::Result<Self::Evaluated>;
58
59    #[cfg(feature = "json")]
60    fn from_json(
61        params: Option<&serde_json::Map<String, serde_json::Value>>,
62    ) -> anyhow::Result<Self>
63    where
64        Self: Sized,
65        Self: serde::de::DeserializeOwned,
66    {
67        let value = params
68            .cloned()
69            .map(serde_json::Value::Object)
70            .unwrap_or_else(|| serde_json::Value::Object(serde_json::Map::new()));
71        serde_path_to_error::deserialize(value).map_err(|error| anyhow::anyhow!(error.to_string()))
72    }
73}
74
75#[derive(Debug, Clone, Default)]
76pub struct DelegateVec<T: Delegated> {
77    pub items: Vec<T::Delegate>,
78}
79
80#[cfg(feature = "json")]
81impl<'de, T> serde::Deserialize<'de> for DelegateVec<T>
82where
83    T: Delegated,
84    T::Delegate: serde::Deserialize<'de>,
85{
86    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
87    where
88        D: serde::Deserializer<'de>,
89    {
90        <Vec<T::Delegate> as serde::Deserialize>::deserialize(deserializer)
91            .map(|items| Self { items })
92    }
93}
94
95impl<T> DelegateEvaluable for DelegateVec<T>
96where
97    T: Delegated,
98    T::Delegate: DelegateEvaluable<Evaluated = T>,
99{
100    type Evaluated = Vec<T>;
101
102    fn eval(&self, ctx: &DelegateEvalContext<'_>) -> crate::Result<Self::Evaluated> {
103        self.items
104            .iter()
105            .enumerate()
106            .map(|(index, value)| {
107                let path = format!("{}[{index}]", ctx.property_path);
108                value.eval(&ctx.child(&path))
109            })
110            .collect()
111    }
112}
113
114impl<T> Delegated for Vec<T>
115where
116    T: Delegated,
117{
118    type Delegate = DelegateVec<T>;
119
120    fn into_delegate(self) -> Self::Delegate {
121        DelegateVec {
122            items: self.into_iter().map(Delegated::into_delegate).collect(),
123        }
124    }
125}