1use super::InspectMut;
7use super::InternalNode;
8use super::Request;
9use super::RequestRoot;
10use super::Response;
11use super::SensitivityLevel;
12use super::UpdateRequest;
13use crate::NumberFormat;
14use crate::ValueKind;
15use alloc::borrow::ToOwned;
16use alloc::string::String;
17use mesh::MeshPayload;
18
19impl Request<'_> {
20 pub fn defer(self) -> Deferred {
23 let (send, recv) = mesh::oneshot();
24 *self.node = InternalNode::Deferred(recv);
25 Deferred {
26 path: self.path.to_owned(),
27 value: self.value.map(|x| x.to_owned()),
28 depth: self.depth,
29 node: send,
30 sensitivity: self.sensitivity,
31 number_format: self.number_format,
32 }
33 }
34}
35
36impl UpdateRequest<'_> {
37 pub fn defer(self) -> DeferredUpdate {
41 let (send, recv) = mesh::oneshot();
42 *self.node = InternalNode::Deferred(recv);
43 DeferredUpdate {
44 value: self.value.to_owned(),
45 node: send,
46 number_format: self.number_format,
47 }
48 }
49}
50
51#[derive(Debug, MeshPayload)]
54pub struct Deferred {
55 path: String,
56 value: Option<String>,
57 depth: usize,
58 node: mesh::OneshotSender<InternalNode>,
59 sensitivity: SensitivityLevel,
60 number_format: NumberFormat,
61}
62
63impl Deferred {
64 pub fn inspect(self, mut obj: impl InspectMut) {
66 let mut root = self.root();
67 obj.inspect_mut(root.request());
68 let node = root.node;
69 self.node.send(node);
70 }
71
72 pub fn respond<F: FnOnce(&mut Response<'_>)>(self, f: F) {
74 let mut root = self.root();
75 f(&mut root.request().respond());
76 let node = root.node;
77 self.node.send(node);
78 }
79
80 pub fn value(self, value: impl Into<ValueKind>) {
82 self.value_(value.into())
83 }
84 fn value_(self, value: ValueKind) {
85 let mut root = self.root();
86 root.request().value(value);
87 let node = root.node;
88 self.node.send(node);
89 }
90
91 pub fn update(self) -> Result<DeferredUpdate, Self> {
95 if self.value.is_some() && self.path.is_empty() {
96 Ok(DeferredUpdate {
97 value: self.value.unwrap(),
98 node: self.node,
99 number_format: self.number_format,
100 })
101 } else {
102 Err(self)
103 }
104 }
105
106 fn root(&self) -> RequestRoot<'_> {
107 RequestRoot::new(
108 &self.path,
109 self.depth,
110 self.value.as_deref(),
111 self.sensitivity,
112 self.number_format,
113 )
114 }
115
116 pub fn ignore(self) {
118 self.node.send(InternalNode::Ignored);
119 }
120
121 #[cfg(feature = "initiate")]
140 pub fn external_request(&self) -> ExternalRequest<'_> {
141 ExternalRequest {
142 path: &self.path,
143 sensitivity: self.sensitivity,
144 request_type: match &self.value {
145 None => ExternalRequestType::Inspect { depth: self.depth },
146 Some(value) => ExternalRequestType::Update { value },
147 },
148 }
149 }
150
151 #[cfg(feature = "initiate")]
158 pub fn complete_external(self, node: super::Node, sensitivity: SensitivityLevel) {
159 if sensitivity > self.sensitivity {
161 return;
162 }
163 if let Some(node) = InternalNode::from_node(node, self.sensitivity) {
164 let node =
167 self.path
168 .split('/')
169 .filter(|s| !s.is_empty())
170 .rev()
171 .fold(node, |node, name| {
172 InternalNode::DirResolved(alloc::vec![crate::InternalEntry {
173 name: name.to_owned(),
174 node,
175 sensitivity,
176 }])
177 });
178
179 self.node.send(node);
180 }
181 }
182
183 pub fn sensitivity(&self) -> SensitivityLevel {
185 self.sensitivity
186 }
187}
188
189impl InternalNode {
190 #[cfg(feature = "initiate")]
191 pub(crate) fn from_node(
192 value: crate::Node,
193 request_sensitivity: SensitivityLevel,
194 ) -> Option<Self> {
195 use crate::Error;
196 use crate::InternalError;
197 use crate::Node;
198
199 let node = match value {
200 Node::Unevaluated => Self::Unevaluated,
201 Node::Failed(err) => Self::Failed(match err {
202 Error::NotFound => return None,
203 Error::Unresolved => InternalError::Unresolved,
204 Error::Mesh(err) => InternalError::Mesh(err),
205 Error::Immutable => InternalError::Immutable,
206 Error::Update(err) => InternalError::Update(err),
207 Error::NotADirectory => InternalError::NotADirectory,
208 Error::Internal => return None,
209 }),
210 Node::Value(v) => Self::Value(v),
211 Node::Dir(children) => Self::DirResolved(
212 children
213 .into_iter()
214 .filter_map(|e| {
215 if e.sensitivity > request_sensitivity {
217 return None;
218 }
219 InternalNode::from_node(e.node, request_sensitivity).map(|v| {
220 crate::InternalEntry {
221 name: e.name,
222 node: v,
223 sensitivity: e.sensitivity,
224 }
225 })
226 })
227 .collect(),
228 ),
229 };
230 Some(node)
231 }
232}
233
234#[cfg(feature = "initiate")]
237pub struct ExternalRequest<'a> {
238 pub path: &'a str,
240 pub request_type: ExternalRequestType<'a>,
242 pub sensitivity: SensitivityLevel,
244}
245
246#[cfg(feature = "initiate")]
248pub enum ExternalRequestType<'a> {
249 Inspect {
251 depth: usize,
253 },
254 Update {
256 value: &'a str,
258 },
259}
260
261#[derive(Debug, MeshPayload)]
264pub struct DeferredUpdate {
265 value: String,
266 node: mesh::OneshotSender<InternalNode>,
267 number_format: NumberFormat,
268}
269
270impl DeferredUpdate {
271 pub fn new_value(&self) -> &str {
273 &self.value
274 }
275
276 pub fn succeed(self, value: impl Into<ValueKind>) {
278 self.succeed_(value.into())
279 }
280 fn succeed_(self, value: ValueKind) {
281 self.node
282 .send(InternalNode::Value(value.with_format(self.number_format)));
283 }
284
285 pub fn fail<E: Into<alloc::boxed::Box<dyn core::error::Error + Send + Sync>>>(self, err: E) {
287 self.node.send(InternalNode::failed(err.into()));
288 }
289}