1use super::InspectMut;
7use super::InternalNode;
8use super::Request;
9use super::Response;
10use super::SensitivityLevel;
11use super::UpdateRequest;
12use crate::NumberFormat;
13use crate::RequestParams;
14use crate::RootParams;
15use crate::ValueKind;
16use alloc::borrow::ToOwned;
17use alloc::boxed::Box;
18use alloc::string::String;
19use mesh::MeshPayload;
20
21impl Request<'_> {
22 pub fn defer(self) -> Deferred {
25 let (send, recv) = mesh::oneshot();
26 *self.node = InternalNode::Deferred(recv);
27 Deferred(Box::new(DeferredInner {
28 path: self.params.path().to_owned(),
29 value: self.params.root.value.map(|x| x.to_owned()),
30 depth: self.params.depth,
31 node: send,
32 sensitivity: self.params.root.sensitivity,
33 number_format: self.params.number_format,
34 }))
35 }
36}
37
38impl UpdateRequest<'_> {
39 pub fn defer(self) -> DeferredUpdate {
43 let (send, recv) = mesh::oneshot();
44 *self.node = InternalNode::Deferred(recv);
45 DeferredUpdate {
46 value: self.value.to_owned(),
47 node: send,
48 number_format: self.number_format,
49 }
50 }
51}
52
53#[derive(Debug, MeshPayload)]
56pub struct Deferred(Box<DeferredInner>);
57
58#[derive(Debug, MeshPayload)]
59struct DeferredInner {
60 path: String,
61 value: Option<String>,
62 depth: usize,
63 node: mesh::OneshotSender<InternalNode>,
64 sensitivity: SensitivityLevel,
65 number_format: NumberFormat,
66}
67
68impl Deferred {
69 pub fn inspect(self, obj: impl InspectMut) {
71 let node = self.params(&self.root()).inspect(obj);
72 self.0.node.send(node);
73 }
74
75 pub fn respond<F: FnOnce(&mut Response<'_>)>(self, f: F) {
77 let node = self.params(&self.root()).with(|req| f(&mut req.respond()));
78 self.0.node.send(node);
79 }
80
81 pub fn value(self, value: impl Into<ValueKind>) {
83 self.value_(value.into())
84 }
85 fn value_(self, value: ValueKind) {
86 let node = self.params(&self.root()).with(|req| req.value(value));
87 self.0.node.send(node);
88 }
89
90 pub fn update(self) -> Result<DeferredUpdate, Self> {
94 if self.0.value.is_some() && self.0.path.is_empty() {
95 Ok(DeferredUpdate {
96 value: self.0.value.unwrap(),
97 node: self.0.node,
98 number_format: self.0.number_format,
99 })
100 } else {
101 Err(self)
102 }
103 }
104
105 fn root(&self) -> RootParams<'_> {
106 RootParams {
107 full_path: &self.0.path,
108 sensitivity: self.0.sensitivity,
109 value: self.0.value.as_deref(),
110 }
111 }
112
113 fn params<'a>(&'a self, root: &'a RootParams<'a>) -> RequestParams<'a> {
114 RequestParams {
115 root,
116 path_start: 0,
117 depth: self.0.depth,
118 number_format: self.0.number_format,
119 }
120 }
121
122 pub fn ignore(self) {
124 self.0.node.send(InternalNode::Ignored);
125 }
126
127 #[cfg(feature = "initiate")]
146 pub fn external_request(&self) -> ExternalRequest<'_> {
147 ExternalRequest {
148 path: &self.0.path,
149 sensitivity: self.0.sensitivity,
150 request_type: match &self.0.value {
151 None => ExternalRequestType::Inspect {
152 depth: self.0.depth,
153 },
154 Some(value) => ExternalRequestType::Update { value },
155 },
156 }
157 }
158
159 #[cfg(feature = "initiate")]
166 pub fn complete_external(self, node: super::Node, sensitivity: SensitivityLevel) {
167 if sensitivity > self.0.sensitivity {
169 return;
170 }
171 if let Some(node) = InternalNode::from_node(node, self.0.sensitivity) {
172 let node =
175 self.0
176 .path
177 .split('/')
178 .filter(|s| !s.is_empty())
179 .rev()
180 .fold(node, |node, name| {
181 InternalNode::DirResolved(alloc::vec![crate::InternalEntry {
182 name: name.to_owned(),
183 node,
184 sensitivity,
185 }])
186 });
187
188 self.0.node.send(node);
189 }
190 }
191
192 pub fn sensitivity(&self) -> SensitivityLevel {
194 self.0.sensitivity
195 }
196}
197
198impl InternalNode {
199 #[cfg(feature = "initiate")]
200 pub(crate) fn from_node(
201 value: crate::Node,
202 request_sensitivity: SensitivityLevel,
203 ) -> Option<Self> {
204 use crate::Error;
205 use crate::InternalError;
206 use crate::Node;
207
208 let node = match value {
209 Node::Unevaluated => Self::Unevaluated,
210 Node::Failed(err) => Self::Failed(match err {
211 Error::NotFound => return None,
212 Error::Unresolved => InternalError::Unresolved,
213 Error::Mesh(err) => InternalError::Mesh(err),
214 Error::Immutable => InternalError::Immutable,
215 Error::Update(err) => InternalError::Update(err),
216 Error::NotADirectory => InternalError::NotADirectory,
217 Error::Internal => return None,
218 }),
219 Node::Value(v) => Self::Value(v),
220 Node::Dir(children) => Self::DirResolved(
221 children
222 .into_iter()
223 .filter_map(|e| {
224 if e.sensitivity > request_sensitivity {
226 return None;
227 }
228 InternalNode::from_node(e.node, request_sensitivity).map(|v| {
229 crate::InternalEntry {
230 name: e.name,
231 node: v,
232 sensitivity: e.sensitivity,
233 }
234 })
235 })
236 .collect(),
237 ),
238 };
239 Some(node)
240 }
241}
242
243#[cfg(feature = "initiate")]
246pub struct ExternalRequest<'a> {
247 pub path: &'a str,
249 pub request_type: ExternalRequestType<'a>,
251 pub sensitivity: SensitivityLevel,
253}
254
255#[cfg(feature = "initiate")]
257pub enum ExternalRequestType<'a> {
258 Inspect {
260 depth: usize,
262 },
263 Update {
265 value: &'a str,
267 },
268}
269
270#[derive(Debug, MeshPayload)]
273pub struct DeferredUpdate {
274 value: String,
275 node: mesh::OneshotSender<InternalNode>,
276 number_format: NumberFormat,
277}
278
279impl DeferredUpdate {
280 pub fn new_value(&self) -> &str {
282 &self.value
283 }
284
285 pub fn succeed(self, value: impl Into<ValueKind>) {
287 self.succeed_(value.into())
288 }
289 fn succeed_(self, value: ValueKind) {
290 self.node
291 .send(InternalNode::Value(value.with_format(self.number_format)));
292 }
293
294 pub fn fail<E: Into<Box<dyn core::error::Error + Send + Sync>>>(self, err: E) {
296 self.node.send(InternalNode::failed(err.into()));
297 }
298}