Skip to main content

trellis_core/
resource_build.rs

1use crate::{
2    CollectionNode, GraphError, GraphResult, MapDiff, PlanContext, PlanError, ResourcePlan,
3    SetDiff, Transaction, resource::ResourcePlanner,
4};
5
6impl<C: 'static, O> Transaction<'_, C, O>
7where
8    O: Clone + PartialEq + 'static,
9{
10    /// Stages a map-diff resource planner.
11    pub fn map_resource_planner<K, V>(
12        &mut self,
13        collection: CollectionNode<K, V>,
14        scope: crate::ScopeId,
15        planner: impl for<'ctx> Fn(
16            &PlanContext<'ctx, MapDiff<K, V>>,
17        ) -> Result<ResourcePlan<C>, PlanError>
18        + Send
19        + Sync
20        + 'static,
21    ) -> GraphResult<()>
22    where
23        K: Clone + Ord + Send + Sync + 'static,
24        V: Clone + PartialEq + Send + Sync + 'static,
25    {
26        self.ensure_open()?;
27        self.working.require_scope_open(scope)?;
28        self.working
29            .validate_map_collection_read::<K, V>(collection.id())?;
30        let resource_planner = ResourcePlanner::new(collection.id(), scope, move |graph| {
31            let Some(diff) = graph.map_diff(collection)? else {
32                return Ok(ResourcePlan::new());
33            };
34            let ctx = PlanContext::new(scope, diff);
35            planner(&ctx).map_err(|error| GraphError::PlanFailed(scope, error))
36        });
37        self.staged_resource_planner_collections
38            .push(collection.id());
39        self.working.resource_planners.push(resource_planner);
40        self.graph_mutated = true;
41        Ok(())
42    }
43
44    /// Stages a set-diff resource planner.
45    pub fn set_resource_planner<K>(
46        &mut self,
47        collection: CollectionNode<K, ()>,
48        scope: crate::ScopeId,
49        planner: impl for<'ctx> Fn(&PlanContext<'ctx, SetDiff<K>>) -> Result<ResourcePlan<C>, PlanError>
50        + Send
51        + Sync
52        + 'static,
53    ) -> GraphResult<()>
54    where
55        K: Clone + Ord + Send + Sync + 'static,
56    {
57        self.ensure_open()?;
58        self.working.require_scope_open(scope)?;
59        self.working
60            .validate_set_collection_read::<K>(collection.id())?;
61        let resource_planner = ResourcePlanner::new(collection.id(), scope, move |graph| {
62            let Some(diff) = graph.set_diff(collection)? else {
63                return Ok(ResourcePlan::new());
64            };
65            let ctx = PlanContext::new(scope, diff);
66            planner(&ctx).map_err(|error| GraphError::PlanFailed(scope, error))
67        });
68        self.staged_resource_planner_collections
69            .push(collection.id());
70        self.working.resource_planners.push(resource_planner);
71        self.graph_mutated = true;
72        Ok(())
73    }
74}