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 + Send + Sync + '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>
85 + Send
86 + Sync
87 + 'static,
88 ) -> GraphResult<DerivedNode<T>>
89 where
90 T: Clone + PartialEq + Send + Sync + 'static,
91 {
92 self.ensure_open()?;
93 let id = self.graph.allocate_node_id();
94 match self
95 .working
96 .derived_direct(id, debug_name, dependencies, derive)
97 {
98 Ok(derived) => {
99 self.graph_mutated = true;
100 self.staged_events
101 .push(AuditEvent::NodeCreated(derived.id()));
102 Ok(derived)
103 }
104 Err(error) => {
105 self.failed.get_or_insert_with(|| error.clone());
106 Err(error)
107 }
108 }
109 }
110
111 pub fn collection<K, V>(
113 &mut self,
114 debug_name: impl Into<String>,
115 dependencies: DependencyList,
116 derive: impl for<'ctx> Fn(&CollectionContext<'ctx, C, O>) -> Result<BTreeMap<K, V>, DeriveError>
117 + Send
118 + Sync
119 + 'static,
120 ) -> GraphResult<CollectionNode<K, V>>
121 where
122 K: Clone + Ord + Send + Sync + 'static,
123 V: Clone + PartialEq + Send + Sync + 'static,
124 {
125 self.map_collection(debug_name, dependencies, derive)
126 }
127
128 pub fn map_collection<K, V>(
130 &mut self,
131 debug_name: impl Into<String>,
132 dependencies: DependencyList,
133 derive: impl for<'ctx> Fn(&CollectionContext<'ctx, C, O>) -> Result<BTreeMap<K, V>, DeriveError>
134 + Send
135 + Sync
136 + 'static,
137 ) -> GraphResult<CollectionNode<K, V>>
138 where
139 K: Clone + Ord + Send + Sync + 'static,
140 V: Clone + PartialEq + Send + Sync + 'static,
141 {
142 self.ensure_open()?;
143 let id = self.graph.allocate_node_id();
144 match self
145 .working
146 .collection_map_direct(id, debug_name, dependencies, derive)
147 {
148 Ok(collection) => {
149 self.graph_mutated = true;
150 self.staged_events
151 .push(AuditEvent::NodeCreated(collection.id()));
152 Ok(collection)
153 }
154 Err(error) => {
155 self.failed.get_or_insert_with(|| error.clone());
156 Err(error)
157 }
158 }
159 }
160
161 pub fn set_collection<K>(
163 &mut self,
164 debug_name: impl Into<String>,
165 dependencies: DependencyList,
166 derive: impl for<'ctx> Fn(&CollectionContext<'ctx, C, O>) -> Result<BTreeSet<K>, DeriveError>
167 + Send
168 + Sync
169 + 'static,
170 ) -> GraphResult<CollectionNode<K, ()>>
171 where
172 K: Clone + Ord + Send + Sync + 'static,
173 {
174 self.ensure_open()?;
175 let id = self.graph.allocate_node_id();
176 match self
177 .working
178 .collection_set_direct(id, debug_name, dependencies, derive)
179 {
180 Ok(collection) => {
181 self.graph_mutated = true;
182 self.staged_events
183 .push(AuditEvent::NodeCreated(collection.id()));
184 Ok(collection)
185 }
186 Err(error) => {
187 self.failed.get_or_insert_with(|| error.clone());
188 Err(error)
189 }
190 }
191 }
192
193 pub fn attach_node_to_scope(
195 &mut self,
196 node: impl crate::NodeHandle,
197 scope: ScopeId,
198 ) -> GraphResult<()> {
199 self.ensure_open()?;
200 let node_id = node.id();
201 match self.working.attach_node_to_scope_direct(node_id, scope) {
202 Ok(()) => {
203 self.graph_mutated = true;
204 self.staged_events.push(AuditEvent::NodeAttached {
205 node: node_id,
206 scope,
207 });
208 Ok(())
209 }
210 Err(error) => {
211 self.failed.get_or_insert_with(|| error.clone());
212 Err(error)
213 }
214 }
215 }
216}