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 }))
73 }
74}
75
76impl UpdateRequest<'_> {
77 pub fn defer(self) -> DeferredUpdate {
81 let (send, recv) = mesh::oneshot();
82 *self.node = InternalNode::Deferred(recv);
83 DeferredUpdate {
84 value: self.value.to_owned(),
85 node: send,
86 number_format: self.number_format,
87 }
88 }
89}
90
91#[derive(Debug, MeshPayload)]
94pub struct Deferred(Box<DeferredInner>);
95
96#[derive(Debug, MeshPayload)]
97struct DeferredInner {
98 path: String,
99 value: Option<String>,
100 depth: usize,
101 node: mesh::OneshotSender<InternalNode>,
102 sensitivity: SensitivityLevel,
103 number_format: NumberFormat,
104}
105
106impl Deferred {
107 pub fn inspect(self, obj: impl InspectMut) {
109 let node = self.params(&self.root()).inspect(obj);
110 self.0.node.send(node);
111 }
112
113 pub fn respond<F: FnOnce(&mut Response<'_>)>(self, f: F) {
115 let node = self.params(&self.root()).with(|req| f(&mut req.respond()));
116 self.0.node.send(node);
117 }
118
119 pub fn value(self, value: impl Into<ValueKind>) {
121 self.value_(value.into())
122 }
123 fn value_(self, value: ValueKind) {
124 let node = self.params(&self.root()).with(|req| req.value(value));
125 self.0.node.send(node);
126 }
127
128 pub fn update(self) -> Result<DeferredUpdate, Self> {
132 if self.0.value.is_some() && self.0.path.is_empty() {
133 Ok(DeferredUpdate {
134 value: self.0.value.unwrap(),
135 node: self.0.node,
136 number_format: self.0.number_format,
137 })
138 } else {
139 Err(self)
140 }
141 }
142
143 fn root(&self) -> RootParams<'_> {
144 RootParams {
145 full_path: &self.0.path,
146 sensitivity: self.0.sensitivity,
147 value: self.0.value.as_deref(),
148 }
149 }
150
151 fn params<'a>(&'a self, root: &'a RootParams<'a>) -> RequestParams<'a> {
152 RequestParams {
153 root,
154 path_start: 0,
155 depth: self.0.depth,
156 number_format: self.0.number_format,
157 }
158 }
159
160 pub fn ignore(self) {
162 self.0.node.send(InternalNode::Ignored);
163 }
164
165 #[cfg(feature = "initiate")]
184 pub fn external_request(&self) -> ExternalRequest<'_> {
185 ExternalRequest {
186 path: &self.0.path,
187 sensitivity: self.0.sensitivity,
188 request_type: match &self.0.value {
189 None => ExternalRequestType::Inspect {
190 depth: self.0.depth,
191 },
192 Some(value) => ExternalRequestType::Update { value },
193 },
194 }
195 }
196
197 #[cfg(feature = "initiate")]
204 pub fn complete_external(self, node: super::Node, sensitivity: SensitivityLevel) {
205 if sensitivity > self.0.sensitivity {
207 return;
208 }
209 if let Some(node) = InternalNode::from_node(node, self.0.sensitivity) {
210 let node =
213 self.0
214 .path
215 .split('/')
216 .filter(|s| !s.is_empty())
217 .rev()
218 .fold(node, |node, name| {
219 InternalNode::DirResolved(alloc::vec![crate::InternalEntry {
220 name: name.to_owned(),
221 node,
222 sensitivity,
223 }])
224 });
225
226 self.0.node.send(node);
227 }
228 }
229
230 pub fn sensitivity(&self) -> SensitivityLevel {
232 self.0.sensitivity
233 }
234}
235
236impl InternalNode {
237 #[cfg(feature = "initiate")]
238 pub(crate) fn from_node(
239 value: crate::Node,
240 request_sensitivity: SensitivityLevel,
241 ) -> Option<Self> {
242 use crate::Error;
243 use crate::InternalError;
244 use crate::Node;
245
246 let node = match value {
247 Node::Unevaluated => Self::Unevaluated,
248 Node::Failed(err) => Self::Failed(match err {
249 Error::NotFound => return None,
250 Error::Unresolved => InternalError::Unresolved,
251 Error::Mesh(err) => InternalError::Mesh(err),
252 Error::Immutable => InternalError::Immutable,
253 Error::Update(err) => InternalError::Update(err),
254 Error::NotADirectory => InternalError::NotADirectory,
255 Error::Internal => return None,
256 }),
257 Node::Value(v) => Self::Value(v),
258 Node::Dir(children) => Self::DirResolved(
259 children
260 .into_iter()
261 .filter_map(|e| {
262 if e.sensitivity > request_sensitivity {
264 return None;
265 }
266 InternalNode::from_node(e.node, request_sensitivity).map(|v| {
267 crate::InternalEntry {
268 name: e.name,
269 node: v,
270 sensitivity: e.sensitivity,
271 }
272 })
273 })
274 .collect(),
275 ),
276 };
277 Some(node)
278 }
279}
280
281#[cfg(feature = "initiate")]
284pub struct ExternalRequest<'a> {
285 pub path: &'a str,
287 pub request_type: ExternalRequestType<'a>,
289 pub sensitivity: SensitivityLevel,
291}
292
293#[cfg(feature = "initiate")]
295pub enum ExternalRequestType<'a> {
296 Inspect {
298 depth: usize,
300 },
301 Update {
303 value: &'a str,
305 },
306}
307
308#[derive(Debug, MeshPayload)]
311pub struct DeferredUpdate {
312 value: String,
313 node: mesh::OneshotSender<InternalNode>,
314 number_format: NumberFormat,
315}
316
317impl DeferredUpdate {
318 pub fn new_value(&self) -> &str {
320 &self.value
321 }
322
323 pub fn succeed(self, value: impl Into<ValueKind>) {
325 self.succeed_(value.into())
326 }
327 fn succeed_(self, value: ValueKind) {
328 self.node
329 .send(InternalNode::Value(value.with_format(self.number_format)));
330 }
331
332 pub fn fail<E: Into<Box<dyn core::error::Error + Send + Sync>>>(self, err: E) {
334 self.node.send(InternalNode::failed(err.into()));
335 }
336}