1use super::InspectMut;
7use super::InternalNode;
8use super::Request;
9use super::RequestRoot;
10use super::Response;
11use super::SensitivityLevel;
12use super::UpdateRequest;
13use super::Value;
14use alloc::borrow::ToOwned;
15use alloc::string::String;
16use mesh::MeshPayload;
17
18impl Request<'_> {
19 pub fn defer(self) -> Deferred {
22 let (send, recv) = mesh::oneshot();
23 *self.node = InternalNode::Deferred(recv);
24 Deferred {
25 path: self.path.to_owned(),
26 value: self.value.map(|x| x.to_owned()),
27 depth: self.depth,
28 node: send,
29 sensitivity: self.sensitivity,
30 }
31 }
32}
33
34impl UpdateRequest<'_> {
35 pub fn defer(self) -> DeferredUpdate {
39 let (send, recv) = mesh::oneshot();
40 *self.node = InternalNode::Deferred(recv);
41 DeferredUpdate {
42 value: self.value.to_owned(),
43 node: send,
44 }
45 }
46}
47
48#[derive(Debug, MeshPayload)]
51pub struct Deferred {
52 path: String,
53 value: Option<String>,
54 depth: usize,
55 node: mesh::OneshotSender<InternalNode>,
56 sensitivity: SensitivityLevel,
57}
58
59impl Deferred {
60 pub fn inspect(self, mut obj: impl InspectMut) {
62 let mut root = self.root();
63 obj.inspect_mut(root.request());
64 let node = root.node;
65 self.node.send(node);
66 }
67
68 pub fn respond<F: FnOnce(&mut Response<'_>)>(self, f: F) {
70 let mut root = self.root();
71 f(&mut root.request().respond());
72 let node = root.node;
73 self.node.send(node);
74 }
75
76 pub fn value(self, value: Value) {
78 let mut root = self.root();
79 root.request().value(value);
80 let node = root.node;
81 self.node.send(node);
82 }
83
84 pub fn update(self) -> Result<DeferredUpdate, Self> {
88 if self.value.is_some() && self.path.is_empty() {
89 Ok(DeferredUpdate {
90 value: self.value.unwrap(),
91 node: self.node,
92 })
93 } else {
94 Err(self)
95 }
96 }
97
98 fn root(&self) -> RequestRoot<'_> {
99 RequestRoot::new(
100 &self.path,
101 self.depth,
102 self.value.as_deref(),
103 self.sensitivity,
104 )
105 }
106
107 pub fn ignore(self) {
109 self.node.send(InternalNode::Ignored);
110 }
111
112 #[cfg(feature = "initiate")]
131 pub fn external_request(&self) -> ExternalRequest<'_> {
132 ExternalRequest {
133 path: &self.path,
134 sensitivity: self.sensitivity,
135 request_type: match &self.value {
136 None => ExternalRequestType::Inspect { depth: self.depth },
137 Some(value) => ExternalRequestType::Update { value },
138 },
139 }
140 }
141
142 #[cfg(feature = "initiate")]
149 pub fn complete_external(self, node: super::Node, sensitivity: SensitivityLevel) {
150 if sensitivity > self.sensitivity {
152 return;
153 }
154 if let Some(node) = InternalNode::from_node(node, self.sensitivity) {
155 let node =
158 self.path
159 .split('/')
160 .filter(|s| !s.is_empty())
161 .rev()
162 .fold(node, |node, name| {
163 InternalNode::DirResolved(alloc::vec![crate::InternalEntry {
164 name: name.to_owned(),
165 node,
166 sensitivity,
167 }])
168 });
169
170 self.node.send(node);
171 }
172 }
173
174 pub fn sensitivity(&self) -> SensitivityLevel {
176 self.sensitivity
177 }
178}
179
180impl InternalNode {
181 #[cfg(feature = "initiate")]
182 pub(crate) fn from_node(
183 value: crate::Node,
184 request_sensitivity: SensitivityLevel,
185 ) -> Option<Self> {
186 use crate::Error;
187 use crate::InternalError;
188 use crate::Node;
189
190 let node = match value {
191 Node::Unevaluated => Self::Unevaluated,
192 Node::Failed(err) => Self::Failed(match err {
193 Error::NotFound => return None,
194 Error::Unresolved => InternalError::Unresolved,
195 Error::Mesh(err) => InternalError::Mesh(err),
196 Error::Immutable => InternalError::Immutable,
197 Error::Update(err) => InternalError::Update(err),
198 Error::NotADirectory => InternalError::NotADirectory,
199 Error::Internal => return None,
200 }),
201 Node::Value(v) => Self::Value(v),
202 Node::Dir(children) => Self::DirResolved(
203 children
204 .into_iter()
205 .filter_map(|e| {
206 if e.sensitivity > request_sensitivity {
208 return None;
209 }
210 InternalNode::from_node(e.node, request_sensitivity).map(|v| {
211 crate::InternalEntry {
212 name: e.name,
213 node: v,
214 sensitivity: e.sensitivity,
215 }
216 })
217 })
218 .collect(),
219 ),
220 };
221 Some(node)
222 }
223}
224
225#[cfg(feature = "initiate")]
228pub struct ExternalRequest<'a> {
229 pub path: &'a str,
231 pub request_type: ExternalRequestType<'a>,
233 pub sensitivity: SensitivityLevel,
235}
236
237#[cfg(feature = "initiate")]
239pub enum ExternalRequestType<'a> {
240 Inspect {
242 depth: usize,
244 },
245 Update {
247 value: &'a str,
249 },
250}
251
252#[derive(Debug, MeshPayload)]
255pub struct DeferredUpdate {
256 value: String,
257 node: mesh::OneshotSender<InternalNode>,
258}
259
260impl DeferredUpdate {
261 pub fn new_value(&self) -> &str {
263 &self.value
264 }
265
266 pub fn succeed(self, value: Value) {
268 self.node.send(InternalNode::Value(value));
269 }
270
271 pub fn fail<E: Into<alloc::boxed::Box<dyn core::error::Error + Send + Sync>>>(self, err: E) {
273 self.node.send(InternalNode::failed(err.into()));
274 }
275}