1use crate::{
2 AuditEvent, CollectionContext, CollectionNode, DependencyList, DeriveContext, DeriveError,
3 DerivedNode, GraphResult, InputNode, ScopeId, Transaction,
4};
5use std::collections::{BTreeMap, BTreeSet};
6
7impl<C: 'static, O> Transaction<'_, C, O>
8where
9 O: Clone + PartialEq + 'static,
10{
11 pub fn create_scope(&mut self, debug_name: impl Into<String>) -> GraphResult<ScopeId> {
13 self.ensure_open()?;
14 let scope = self.graph.allocate_scope_id();
15 let scope = self
16 .working
17 .create_scope_with_parent_direct(scope, debug_name, None)?;
18 self.graph_mutated = true;
19 self.staged_events.push(AuditEvent::ScopeCreated(scope));
20 Ok(scope)
21 }
22
23 pub fn create_scope_with_parent(
25 &mut self,
26 debug_name: impl Into<String>,
27 parent: Option<ScopeId>,
28 ) -> GraphResult<ScopeId> {
29 self.ensure_open()?;
30 let scope = self.graph.allocate_scope_id();
31 match self
32 .working
33 .create_scope_with_parent_direct(scope, debug_name, parent)
34 {
35 Ok(scope) => {
36 self.graph_mutated = true;
37 self.staged_events.push(AuditEvent::ScopeCreated(scope));
38 Ok(scope)
39 }
40 Err(error) => {
41 self.failed.get_or_insert_with(|| error.clone());
42 Err(error)
43 }
44 }
45 }
46
47 pub fn close_scope(&mut self, scope: ScopeId) -> GraphResult<()> {
49 self.ensure_open()?;
50 match self.working.close_scope_direct(scope) {
51 Ok(closed_scopes) => {
52 if !closed_scopes.is_empty() {
53 self.graph_mutated = true;
54 }
55 self.staged_events
56 .extend(closed_scopes.into_iter().map(AuditEvent::ScopeClosed));
57 Ok(())
58 }
59 Err(error) => {
60 self.failed.get_or_insert_with(|| error.clone());
61 Err(error)
62 }
63 }
64 }
65
66 pub fn input<T>(&mut self, debug_name: impl Into<String>) -> GraphResult<InputNode<T>>
68 where
69 T: Clone + PartialEq + 'static,
70 {
71 self.ensure_open()?;
72 let id = self.graph.allocate_node_id();
73 let input = self.working.input_direct(id, debug_name)?;
74 self.graph_mutated = true;
75 self.staged_events.push(AuditEvent::NodeCreated(input.id()));
76 Ok(input)
77 }
78
79 pub fn derived<T>(
81 &mut self,
82 debug_name: impl Into<String>,
83 dependencies: DependencyList,
84 derive: impl for<'ctx> Fn(&DeriveContext<'ctx, C, O>) -> Result<T, DeriveError> + 'static,
85 ) -> GraphResult<DerivedNode<T>>
86 where
87 T: Clone + PartialEq + 'static,
88 {
89 self.ensure_open()?;
90 let id = self.graph.allocate_node_id();
91 match self
92 .working
93 .derived_direct(id, debug_name, dependencies, derive)
94 {
95 Ok(derived) => {
96 self.graph_mutated = true;
97 self.staged_events
98 .push(AuditEvent::NodeCreated(derived.id()));
99 Ok(derived)
100 }
101 Err(error) => {
102 self.failed.get_or_insert_with(|| error.clone());
103 Err(error)
104 }
105 }
106 }
107
108 pub fn collection<K, V>(
110 &mut self,
111 debug_name: impl Into<String>,
112 dependencies: DependencyList,
113 derive: impl for<'ctx> Fn(&CollectionContext<'ctx, C, O>) -> Result<BTreeMap<K, V>, DeriveError>
114 + 'static,
115 ) -> GraphResult<CollectionNode<K, V>>
116 where
117 K: Clone + Ord + 'static,
118 V: Clone + PartialEq + 'static,
119 {
120 self.map_collection(debug_name, dependencies, derive)
121 }
122
123 pub fn map_collection<K, V>(
125 &mut self,
126 debug_name: impl Into<String>,
127 dependencies: DependencyList,
128 derive: impl for<'ctx> Fn(&CollectionContext<'ctx, C, O>) -> Result<BTreeMap<K, V>, DeriveError>
129 + 'static,
130 ) -> GraphResult<CollectionNode<K, V>>
131 where
132 K: Clone + Ord + 'static,
133 V: Clone + PartialEq + 'static,
134 {
135 self.ensure_open()?;
136 let id = self.graph.allocate_node_id();
137 match self
138 .working
139 .collection_map_direct(id, debug_name, dependencies, derive)
140 {
141 Ok(collection) => {
142 self.graph_mutated = true;
143 self.staged_events
144 .push(AuditEvent::NodeCreated(collection.id()));
145 Ok(collection)
146 }
147 Err(error) => {
148 self.failed.get_or_insert_with(|| error.clone());
149 Err(error)
150 }
151 }
152 }
153
154 pub fn set_collection<K>(
156 &mut self,
157 debug_name: impl Into<String>,
158 dependencies: DependencyList,
159 derive: impl for<'ctx> Fn(&CollectionContext<'ctx, C, O>) -> Result<BTreeSet<K>, DeriveError>
160 + 'static,
161 ) -> GraphResult<CollectionNode<K, ()>>
162 where
163 K: Clone + Ord + 'static,
164 {
165 self.ensure_open()?;
166 let id = self.graph.allocate_node_id();
167 match self
168 .working
169 .collection_set_direct(id, debug_name, dependencies, derive)
170 {
171 Ok(collection) => {
172 self.graph_mutated = true;
173 self.staged_events
174 .push(AuditEvent::NodeCreated(collection.id()));
175 Ok(collection)
176 }
177 Err(error) => {
178 self.failed.get_or_insert_with(|| error.clone());
179 Err(error)
180 }
181 }
182 }
183
184 pub fn attach_node_to_scope(
186 &mut self,
187 node: impl crate::NodeHandle,
188 scope: ScopeId,
189 ) -> GraphResult<()> {
190 self.ensure_open()?;
191 let node_id = node.id();
192 match self.working.attach_node_to_scope_direct(node_id, scope) {
193 Ok(()) => {
194 self.graph_mutated = true;
195 self.staged_events.push(AuditEvent::NodeAttached {
196 node: node_id,
197 scope,
198 });
199 Ok(())
200 }
201 Err(error) => {
202 self.failed.get_or_insert_with(|| error.clone());
203 Err(error)
204 }
205 }
206 }
207}