trellis_core/
resource_build.rs1use crate::{
2 CollectionNode, GraphError, GraphResult, MapDiff, PlanContext, PlanError, ResourceKey,
3 ResourcePlan, SetDiff, Transaction, resource::ResourcePlanner,
4};
5
6impl<C: 'static> Transaction<'_, C> {
7 pub fn map_resource_planner<K, V>(
9 &mut self,
10 collection: CollectionNode<K, V>,
11 scope: crate::ScopeId,
12 planner: impl for<'ctx> Fn(
13 &PlanContext<'ctx, MapDiff<K, V>>,
14 ) -> Result<ResourcePlan<C>, PlanError>
15 + Send
16 + Sync
17 + 'static,
18 ) -> GraphResult<()>
19 where
20 K: Clone + Ord + Send + Sync + 'static,
21 V: Clone + PartialEq + Send + Sync + 'static,
22 {
23 self.ensure_open()?;
24 self.working.require_scope_open(scope)?;
25 self.working
26 .validate_map_collection_read::<K, V>(collection.id())?;
27 let resource_planner = ResourcePlanner::new(collection.id(), scope, move |graph| {
28 let Some(diff) = graph.map_diff(collection)? else {
29 return Ok(ResourcePlan::new());
30 };
31 let ctx = PlanContext::new(scope, diff);
32 planner(&ctx).map_err(|error| GraphError::PlanFailed(scope, error))
33 });
34 self.staged_resource_planner_collections
35 .push(collection.id());
36 self.working.resource_planners.push(resource_planner);
37 self.graph_mutated = true;
38 Ok(())
39 }
40
41 pub fn set_resource_planner<K>(
43 &mut self,
44 collection: CollectionNode<K, ()>,
45 scope: crate::ScopeId,
46 planner: impl for<'ctx> Fn(&PlanContext<'ctx, SetDiff<K>>) -> Result<ResourcePlan<C>, PlanError>
47 + Send
48 + Sync
49 + 'static,
50 ) -> GraphResult<()>
51 where
52 K: Clone + Ord + Send + Sync + 'static,
53 {
54 self.ensure_open()?;
55 self.working.require_scope_open(scope)?;
56 self.working
57 .validate_set_collection_read::<K>(collection.id())?;
58 let resource_planner = ResourcePlanner::new(collection.id(), scope, move |graph| {
59 let Some(diff) = graph.set_diff(collection)? else {
60 return Ok(ResourcePlan::new());
61 };
62 let ctx = PlanContext::new(scope, diff);
63 planner(&ctx).map_err(|error| GraphError::PlanFailed(scope, error))
64 });
65 self.staged_resource_planner_collections
66 .push(collection.id());
67 self.working.resource_planners.push(resource_planner);
68 self.graph_mutated = true;
69 Ok(())
70 }
71
72 pub fn open_close_planner<K>(
74 &mut self,
75 collection: CollectionNode<K, ()>,
76 scope: crate::ScopeId,
77 key: impl Fn(&K) -> ResourceKey + Send + Sync + 'static,
78 open: impl Fn(&K) -> C + Send + Sync + 'static,
79 ) -> GraphResult<()>
80 where
81 K: Clone + Ord + Send + Sync + 'static,
82 {
83 self.set_resource_planner(collection, scope, move |ctx| {
84 let mut plan = ResourcePlan::new();
85 for added in &ctx.diff().added {
86 plan.open(key(&added.value), ctx.scope(), open(&added.value));
87 }
88 for removed in &ctx.diff().removed {
89 plan.close(key(&removed.value), ctx.scope());
90 }
91 Ok(plan)
92 })
93 }
94}