1use crate::{Graph, GraphResult, NodeId, ScopeId};
2use core::fmt;
3use std::sync::Arc;
4
5#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub struct ResourceKey(Box<str>);
9
10impl ResourceKey {
11 pub fn new(key: impl Into<Box<str>>) -> Self {
13 Self(key.into())
14 }
15
16 pub fn wildcard(key: impl AsRef<str>) -> Self {
21 Self::new(format!("wildcard:{}", key.as_ref()))
22 }
23
24 pub fn as_str(&self) -> &str {
26 &self.0
27 }
28}
29
30impl fmt::Debug for ResourceKey {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 f.debug_tuple("ResourceKey").field(&self.0).finish()
33 }
34}
35
36#[derive(Clone, Debug, Eq, PartialEq)]
38#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
39pub enum ResourceCommand<C> {
40 Open {
42 key: ResourceKey,
44 scope: ScopeId,
46 command: C,
48 },
49 Close {
51 key: ResourceKey,
53 scope: ScopeId,
55 },
56 Replace {
58 key: ResourceKey,
60 scope: ScopeId,
62 command: C,
64 },
65 Refresh {
67 key: ResourceKey,
69 scope: ScopeId,
71 command: C,
73 },
74}
75
76impl<C> ResourceCommand<C> {
77 pub fn key(&self) -> &ResourceKey {
79 match self {
80 Self::Open { key, .. }
81 | Self::Close { key, .. }
82 | Self::Replace { key, .. }
83 | Self::Refresh { key, .. } => key,
84 }
85 }
86
87 pub fn scope(&self) -> ScopeId {
89 match self {
90 Self::Open { scope, .. }
91 | Self::Close { scope, .. }
92 | Self::Replace { scope, .. }
93 | Self::Refresh { scope, .. } => *scope,
94 }
95 }
96}
97
98#[derive(Clone, Debug, Eq, PartialEq)]
100#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
101pub struct ResourcePlan<C> {
102 commands: Vec<ResourceCommand<C>>,
103}
104
105impl<C> ResourcePlan<C> {
106 pub fn new() -> Self {
108 Self {
109 commands: Vec::new(),
110 }
111 }
112
113 pub fn open(&mut self, key: ResourceKey, scope: ScopeId, command: C) {
115 self.commands.push(ResourceCommand::Open {
116 key,
117 scope,
118 command,
119 });
120 }
121
122 pub fn close(&mut self, key: ResourceKey, scope: ScopeId) {
124 self.commands.push(ResourceCommand::Close { key, scope });
125 }
126
127 pub fn replace(&mut self, key: ResourceKey, scope: ScopeId, command: C) {
129 self.commands.push(ResourceCommand::Replace {
130 key,
131 scope,
132 command,
133 });
134 }
135
136 pub fn refresh(&mut self, key: ResourceKey, scope: ScopeId, command: C) {
138 self.commands.push(ResourceCommand::Refresh {
139 key,
140 scope,
141 command,
142 });
143 }
144
145 pub fn commands(&self) -> &[ResourceCommand<C>] {
147 &self.commands
148 }
149
150 pub fn into_commands(self) -> Vec<ResourceCommand<C>> {
152 self.commands
153 }
154
155 pub(crate) fn append(&mut self, other: ResourcePlan<C>) {
156 self.commands.extend(other.commands);
157 }
158}
159
160impl<C> Default for ResourcePlan<C> {
161 fn default() -> Self {
162 Self::new()
163 }
164}
165
166pub struct PlanContext<'graph, D> {
168 scope: ScopeId,
169 diff: &'graph D,
170}
171
172impl<'graph, D> PlanContext<'graph, D> {
173 pub(crate) fn new(scope: ScopeId, diff: &'graph D) -> Self {
174 Self { scope, diff }
175 }
176
177 pub fn scope(&self) -> ScopeId {
179 self.scope
180 }
181
182 pub fn diff(&self) -> &'graph D {
184 self.diff
185 }
186}
187
188type PlannerFn<C, O> = dyn Fn(&Graph<C, O>) -> GraphResult<ResourcePlan<C>>;
189
190pub(crate) struct ResourcePlanner<C, O> {
191 pub(crate) collection: NodeId,
192 pub(crate) scope: ScopeId,
193 run: Arc<PlannerFn<C, O>>,
194}
195
196impl<C, O> Clone for ResourcePlanner<C, O> {
197 fn clone(&self) -> Self {
198 Self {
199 collection: self.collection,
200 scope: self.scope,
201 run: Arc::clone(&self.run),
202 }
203 }
204}
205
206impl<C, O> ResourcePlanner<C, O> {
207 pub(crate) fn new(
208 collection: NodeId,
209 scope: ScopeId,
210 run: impl Fn(&Graph<C, O>) -> GraphResult<ResourcePlan<C>> + 'static,
211 ) -> Self {
212 Self {
213 collection,
214 scope,
215 run: Arc::new(run),
216 }
217 }
218
219 pub(crate) fn run(&self, graph: &Graph<C, O>) -> GraphResult<ResourcePlan<C>> {
220 (self.run)(graph)
221 }
222}