1use crate::{Graph, GraphResult, NodeId, ResourceKey, ScopeId};
2use std::sync::Arc;
3
4#[derive(Clone, Debug, Eq, PartialEq)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7pub enum ResourceCommand<C> {
8 Open {
10 key: ResourceKey,
12 scope: ScopeId,
14 command: C,
16 },
17 Close {
19 key: ResourceKey,
21 scope: ScopeId,
23 },
24 Replace {
26 key: ResourceKey,
28 scope: ScopeId,
30 command: C,
32 },
33 Refresh {
35 key: ResourceKey,
37 scope: ScopeId,
39 command: C,
41 },
42}
43
44impl<C> ResourceCommand<C> {
45 pub fn key(&self) -> &ResourceKey {
47 match self {
48 Self::Open { key, .. }
49 | Self::Close { key, .. }
50 | Self::Replace { key, .. }
51 | Self::Refresh { key, .. } => key,
52 }
53 }
54
55 pub fn scope(&self) -> ScopeId {
57 match self {
58 Self::Open { scope, .. }
59 | Self::Close { scope, .. }
60 | Self::Replace { scope, .. }
61 | Self::Refresh { scope, .. } => *scope,
62 }
63 }
64}
65
66#[derive(Clone, Debug, Eq, PartialEq)]
68#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
69pub struct ResourcePlan<C> {
70 commands: Vec<ResourceCommand<C>>,
71}
72
73impl<C> ResourcePlan<C> {
74 pub fn new() -> Self {
76 Self {
77 commands: Vec::new(),
78 }
79 }
80
81 pub fn open(&mut self, key: ResourceKey, scope: ScopeId, command: C) {
83 self.commands.push(ResourceCommand::Open {
84 key,
85 scope,
86 command,
87 });
88 }
89
90 pub fn close(&mut self, key: ResourceKey, scope: ScopeId) {
92 self.commands.push(ResourceCommand::Close { key, scope });
93 }
94
95 pub fn replace(&mut self, key: ResourceKey, scope: ScopeId, command: C) {
97 self.commands.push(ResourceCommand::Replace {
98 key,
99 scope,
100 command,
101 });
102 }
103
104 pub fn refresh(&mut self, key: ResourceKey, scope: ScopeId, command: C) {
106 self.commands.push(ResourceCommand::Refresh {
107 key,
108 scope,
109 command,
110 });
111 }
112
113 pub fn commands(&self) -> &[ResourceCommand<C>] {
115 &self.commands
116 }
117
118 pub fn into_commands(self) -> Vec<ResourceCommand<C>> {
120 self.commands
121 }
122
123 pub(crate) fn append(&mut self, other: ResourcePlan<C>) {
124 self.commands.extend(other.commands);
125 }
126}
127
128impl<C> Default for ResourcePlan<C> {
129 fn default() -> Self {
130 Self::new()
131 }
132}
133
134pub struct PlanContext<'graph, D> {
136 scope: ScopeId,
137 diff: &'graph D,
138}
139
140impl<'graph, D> PlanContext<'graph, D> {
141 pub(crate) fn new(scope: ScopeId, diff: &'graph D) -> Self {
142 Self { scope, diff }
143 }
144
145 pub fn scope(&self) -> ScopeId {
147 self.scope
148 }
149
150 pub fn diff(&self) -> &'graph D {
152 self.diff
153 }
154}
155
156type PlannerFn<C> = dyn Fn(&Graph<C>) -> GraphResult<ResourcePlan<C>> + Send + Sync;
157
158pub(crate) struct ResourcePlanner<C> {
159 pub(crate) collection: NodeId,
160 pub(crate) scope: ScopeId,
161 run: Arc<PlannerFn<C>>,
162}
163
164impl<C> Clone for ResourcePlanner<C> {
165 fn clone(&self) -> Self {
166 Self {
167 collection: self.collection,
168 scope: self.scope,
169 run: Arc::clone(&self.run),
170 }
171 }
172}
173
174impl<C> ResourcePlanner<C> {
175 pub(crate) fn new(
176 collection: NodeId,
177 scope: ScopeId,
178 run: impl Fn(&Graph<C>) -> GraphResult<ResourcePlan<C>> + Send + Sync + 'static,
179 ) -> Self {
180 Self {
181 collection,
182 scope,
183 run: Arc::new(run),
184 }
185 }
186
187 pub(crate) fn run(&self, graph: &Graph<C>) -> GraphResult<ResourcePlan<C>> {
188 (self.run)(graph)
189 }
190}