1use super::InspectMut;
7use super::InternalNode;
8use super::Request;
9use super::Response;
10use super::SensitivityLevel;
11use super::UpdateRequest;
12use crate::Inspect;
13use crate::NumberFormat;
14use crate::RequestParams;
15use crate::RootParams;
16use crate::ValueKind;
17use alloc::borrow::ToOwned;
18use alloc::boxed::Box;
19use alloc::string::String;
20use mesh::MeshPayload;
21
22pub fn send<'a, S: 'a + mesh::rpc::RpcSend + Copy, F: 'a + Fn(Deferred) -> S::Message>(
38 sender: S,
39 map: F,
40) -> AsDeferred<S, F> {
41 AsDeferred(sender, map)
42}
43
44pub struct AsDeferred<S, F>(S, F);
46
47impl<S: mesh::rpc::RpcSend + Copy, F: Fn(Deferred) -> S::Message> Inspect for AsDeferred<S, F> {
48 fn inspect(&self, req: Request<'_>) {
49 self.0.send_rpc(self.1(req.defer()));
50 }
51}
52
53impl<S: mesh::rpc::RpcSend + Copy, F: Fn(Deferred) -> S::Message> InspectMut for AsDeferred<S, F> {
54 fn inspect_mut(&mut self, req: Request<'_>) {
55 self.0.send_rpc(self.1(req.defer()));
56 }
57}
58
59impl Request<'_> {
60 pub fn defer(self) -> Deferred {
63 let (send, recv) = mesh::oneshot();
64 *self.node = InternalNode::Deferred(recv);
65 Deferred(Box::new(DeferredInner {
66 path: self.params.path().to_owned(),
67 value: self.params.root.value.map(|x| x.to_owned()),
68 depth: self.params.depth,
69 node: send,
70 sensitivity: self.params.root.sensitivity,
71 number_format: self.params.number_format,
72 parent_sensitivity: self.params.parent_sensitivity,
73 }))
74 }
75}
76
77impl UpdateRequest<'_> {
78 pub fn defer(self) -> DeferredUpdate {
82 let (send, recv) = mesh::oneshot();
83 *self.node = InternalNode::Deferred(recv);
84 DeferredUpdate {
85 value: self.value.to_owned(),
86 node: send,
87 number_format: self.number_format,
88 }
89 }
90}
91
92#[derive(Debug, MeshPayload)]
95pub struct Deferred(Box<DeferredInner>);
96
97#[derive(Debug, MeshPayload)]
98struct DeferredInner {
99 path: String,
100 value: Option<String>,
101 depth: usize,
102 node: mesh::OneshotSender<InternalNode>,
103 sensitivity: SensitivityLevel,
104 parent_sensitivity: SensitivityLevel,
105 number_format: NumberFormat,
106}
107
108impl Deferred {
109 pub fn inspect(self, obj: impl InspectMut) {
111 let node = self.params(&self.root()).inspect(obj);
112 self.0.node.send(node);
113 }
114
115 pub fn respond<F: FnOnce(&mut Response<'_>)>(self, f: F) {
117 let node = self.params(&self.root()).with(|req| f(&mut req.respond()));
118 self.0.node.send(node);
119 }
120
121 pub fn value(self, value: impl Into<ValueKind>) {
123 self.value_(value.into())
124 }
125 fn value_(self, value: ValueKind) {
126 let node = self.params(&self.root()).with(|req| req.value(value));
127 self.0.node.send(node);
128 }
129
130 pub fn update(self) -> Result<DeferredUpdate, Self> {
134 if self.0.path.is_empty()
135 && let Some(value) = self.0.value
136 {
137 Ok(DeferredUpdate {
138 value,
139 node: self.0.node,
140 number_format: self.0.number_format,
141 })
142 } else {
143 Err(self)
144 }
145 }
146
147 fn root(&self) -> RootParams<'_> {
148 RootParams {
149 full_path: &self.0.path,
150 sensitivity: self.0.sensitivity,
151 value: self.0.value.as_deref(),
152 }
153 }
154
155 fn params<'a>(&'a self, root: &'a RootParams<'a>) -> RequestParams<'a> {
156 RequestParams {
157 root,
158 path_start: 0,
159 depth: self.0.depth,
160 number_format: self.0.number_format,
161 parent_sensitivity: self.0.parent_sensitivity,
162 }
163 }
164
165 pub fn ignore(self) {
167 self.0.node.send(InternalNode::Ignored);
168 }
169
170 #[cfg(feature = "initiate")]
189 pub fn external_request(&self) -> ExternalRequest<'_> {
190 ExternalRequest {
191 path: &self.0.path,
192 sensitivity: self.0.sensitivity,
193 request_type: match &self.0.value {
194 None => ExternalRequestType::Inspect {
195 depth: self.0.depth,
196 },
197 Some(value) => ExternalRequestType::Update { value },
198 },
199 }
200 }
201
202 #[cfg(feature = "initiate")]
209 pub fn complete_external(self, node: super::Node, sensitivity: SensitivityLevel) {
210 if sensitivity > self.0.sensitivity {
212 return;
213 }
214 if let Some(node) = InternalNode::from_node(node, self.0.sensitivity) {
215 let node =
218 self.0
219 .path
220 .split('/')
221 .filter(|s| !s.is_empty())
222 .rev()
223 .fold(node, |node, name| {
224 InternalNode::DirResolved(alloc::vec![crate::InternalEntry {
225 name: name.to_owned(),
226 node,
227 sensitivity,
228 }])
229 });
230
231 self.0.node.send(node);
232 }
233 }
234
235 pub fn sensitivity(&self) -> SensitivityLevel {
237 self.0.sensitivity
238 }
239}
240
241impl InternalNode {
242 #[cfg(feature = "initiate")]
243 pub(crate) fn from_node(
244 value: crate::Node,
245 request_sensitivity: SensitivityLevel,
246 ) -> Option<Self> {
247 use crate::Error;
248 use crate::InternalError;
249 use crate::Node;
250
251 let node = match value {
252 Node::Unevaluated => Self::Unevaluated,
253 Node::Failed(err) => Self::Failed(match err {
254 Error::NotFound => return None,
255 Error::Unresolved => InternalError::Unresolved,
256 Error::Mesh(err) => InternalError::Mesh(err),
257 Error::Immutable => InternalError::Immutable,
258 Error::Update(err) => InternalError::Update(err),
259 Error::NotADirectory => InternalError::NotADirectory,
260 Error::Internal => return None,
261 }),
262 Node::Value(v) => Self::Value(v),
263 Node::Dir(children) => Self::DirResolved(
264 children
265 .into_iter()
266 .filter_map(|e| {
267 if e.sensitivity > request_sensitivity {
269 return None;
270 }
271 InternalNode::from_node(e.node, request_sensitivity).map(|v| {
272 crate::InternalEntry {
273 name: e.name,
274 node: v,
275 sensitivity: e.sensitivity,
276 }
277 })
278 })
279 .collect(),
280 ),
281 };
282 Some(node)
283 }
284}
285
286#[cfg(feature = "initiate")]
289pub struct ExternalRequest<'a> {
290 pub path: &'a str,
292 pub request_type: ExternalRequestType<'a>,
294 pub sensitivity: SensitivityLevel,
296}
297
298#[cfg(feature = "initiate")]
300pub enum ExternalRequestType<'a> {
301 Inspect {
303 depth: usize,
305 },
306 Update {
308 value: &'a str,
310 },
311}
312
313#[derive(Debug, MeshPayload)]
316pub struct DeferredUpdate {
317 value: String,
318 node: mesh::OneshotSender<InternalNode>,
319 number_format: NumberFormat,
320}
321
322impl DeferredUpdate {
323 pub fn new_value(&self) -> &str {
325 &self.value
326 }
327
328 pub fn succeed(self, value: impl Into<ValueKind>) {
330 self.succeed_(value.into())
331 }
332 fn succeed_(self, value: ValueKind) {
333 self.node
334 .send(InternalNode::Value(value.with_format(self.number_format)));
335 }
336
337 pub fn fail<E: Into<Box<dyn core::error::Error + Send + Sync>>>(self, err: E) {
339 self.node.send(InternalNode::failed(err.into()));
340 }
341}