1pub mod util;
2
3pub struct PlannerInit<ERT> {
6 empty_rtt: ERT,
7}
8
9impl<ERT> PlannerInit<ERT> {
10 pub fn new(empty_rtt: ERT) -> PlannerInit<ERT> {
11 PlannerInit { empty_rtt, }
12 }
13}
14
15pub trait TransAddRoot<ERT> {
16 type NonEmptyRtt;
17 type Error;
18
19 fn add_root(self, empty_rtt: ERT) -> Result<Self::NonEmptyRtt, Self::Error>;
20}
21
22impl<ERT, F, RT, E> TransAddRoot<ERT> for F where F: FnOnce(ERT) -> Result<RT, E> {
23 type NonEmptyRtt = RT;
24 type Error = E;
25
26 fn add_root(self, empty_rtt: ERT) -> Result<Self::NonEmptyRtt, Self::Error> {
27 (self)(empty_rtt)
28 }
29}
30
31impl<ERT> PlannerInit<ERT> {
32 pub fn add_root<TR>(self, trans: TR) ->
33 Result<Planner<TR::NonEmptyRtt>, TR::Error>
34 where TR: TransAddRoot<ERT>
35 {
36 Ok(Planner { rtt: trans.add_root(self.empty_rtt)?, })
37 }
38
39 pub fn add_root_ok<TR>(self, trans: TR) -> Planner<TR::NonEmptyRtt>
40 where TR: TransAddRoot<ERT, Error = util::NeverError>
41 {
42 self.add_root(trans)
43 .unwrap_or_else(|_: util::NeverError| unreachable!())
44 }
45}
46
47pub struct Planner<RT> {
50 rtt: RT,
51}
52
53pub trait TransRootNode<RT> {
54 type RttNodeRef;
55 type Error;
56
57 fn root_node(self, rtt: &mut RT) -> Result<Self::RttNodeRef, Self::Error>;
58}
59
60impl<RT, F, NR, E> TransRootNode<RT> for F where F: FnOnce(&mut RT) -> Result<NR, E> {
61 type RttNodeRef = NR;
62 type Error = E;
63
64 fn root_node(self, rtt: &mut RT) -> Result<Self::RttNodeRef, Self::Error> {
65 (self)(rtt)
66 }
67}
68
69impl<RT> Planner<RT> {
70 pub fn root_node<TR>(mut self, trans: TR) ->
71 Result<PlannerRttNode<RT, TR::RttNodeRef>, TR::Error>
72 where TR: TransRootNode<RT>
73 {
74 Ok(PlannerRttNode {
75 node_ref: trans.root_node(&mut self.rtt)?,
76 rtt: self.rtt,
77 })
78 }
79
80 pub fn root_node_ok<TR>(self, trans: TR) -> PlannerRttNode<RT, TR::RttNodeRef>
81 where TR: TransRootNode<RT, Error = util::NeverError>
82 {
83 self.root_node(trans)
84 .unwrap_or_else(|_: util::NeverError| unreachable!())
85 }
86}
87
88pub struct PlannerRttNode<RT, NR> {
91 rtt: RT,
92 node_ref: NR,
93}
94
95pub trait TransIntoPath<RT, NR> {
96 type RttPath;
97 type Error;
98
99 fn into_path(self, rtt: RT, node_ref: NR) -> Result<Self::RttPath, Self::Error>;
100}
101
102impl<RT, NR, F, P, E> TransIntoPath<RT, NR> for F where F: FnOnce(RT, NR) -> Result<P, E> {
103 type RttPath = P;
104 type Error = E;
105
106 fn into_path(self, rtt: RT, node_ref: NR) -> Result<Self::RttPath, Self::Error> {
107 (self)(rtt, node_ref)
108 }
109}
110
111pub trait TransPrepareSample<RT, NR> {
112 type Error;
113
114 fn prepare_sample(self, rtt: &mut RT, node_ref: NR) -> Result<(), Self::Error>;
115}
116
117impl<RT, NR, F, E> TransPrepareSample<RT, NR> for F where F: FnOnce(&mut RT, NR) -> Result<(), E> {
118 type Error = E;
119
120 fn prepare_sample(self, rtt: &mut RT, node_ref: NR) -> Result<(), Self::Error> {
121 (self)(rtt, node_ref)
122 }
123}
124
125impl<RT, NR> PlannerRttNode<RT, NR> {
126 pub fn rtt(&self) -> &RT {
127 &self.rtt
128 }
129
130 pub fn node_ref(&self) -> &NR {
131 &self.node_ref
132 }
133
134 pub fn into_path<TR>(self, trans: TR) -> Result<TR::RttPath, TR::Error>
135 where TR: TransIntoPath<RT, NR>
136 {
137 trans.into_path(self.rtt, self.node_ref)
138 }
139
140 pub fn into_path_ok<TR>(self, trans: TR) -> TR::RttPath
141 where TR: TransIntoPath<RT, NR, Error = util::NeverError>
142 {
143 self.into_path(trans)
144 .unwrap_or_else(|_: util::NeverError| unreachable!())
145 }
146
147 pub fn prepare_sample<TR>(mut self, trans: TR) -> Result<PlannerReadyToSample<RT>, TR::Error>
148 where TR: TransPrepareSample<RT, NR>
149 {
150 let () = trans.prepare_sample(&mut self.rtt, self.node_ref)?;
151 Ok(PlannerReadyToSample { rtt: self.rtt, })
152 }
153
154 pub fn prepare_sample_ok<TR>(self, trans: TR) -> PlannerReadyToSample<RT>
155 where TR: TransPrepareSample<RT, NR, Error = util::NeverError>
156 {
157 self.prepare_sample(trans)
158 .unwrap_or_else(|_: util::NeverError| unreachable!())
159 }
160}
161
162pub struct PlannerReadyToSample<RT> {
165 rtt: RT,
166}
167
168pub trait TransSample<RT> {
169 type Sample;
170 type Error;
171
172 fn sample(self, rtt: &mut RT) -> Result<Self::Sample, Self::Error>;
173}
174
175impl<RT, F, S, E> TransSample<RT> for F where F: FnOnce(&mut RT) -> Result<S, E> {
176 type Sample = S;
177 type Error = E;
178
179 fn sample(self, rtt: &mut RT) -> Result<Self::Sample, Self::Error> {
180 (self)(rtt)
181 }
182}
183
184impl<RT> PlannerReadyToSample<RT> {
185 pub fn rtt(&self) -> &RT {
186 &self.rtt
187 }
188
189 pub fn sample<TR>(mut self, trans: TR) ->
190 Result<PlannerSample<RT, TR::Sample>, TR::Error>
191 where TR: TransSample<RT>
192 {
193 let sample = trans.sample(&mut self.rtt)?;
194 Ok(PlannerSample { rtt: self.rtt, sample, })
195 }
196
197 pub fn sample_ok<TR>(self, trans: TR) -> PlannerSample<RT, TR::Sample>
198 where TR: TransSample<RT, Error = util::NeverError>
199 {
200 self.sample(trans)
201 .unwrap_or_else(|_: util::NeverError| unreachable!())
202 }
203}
204
205pub struct PlannerSample<RT, S> {
208 rtt: RT,
209 sample: S,
210}
211
212pub trait TransClosestToSample<RT, S> {
213 type RttNodeRef;
214 type Error;
215
216 fn closest_to_sample(self, rtt: &mut RT, sample: &S) -> Result<Self::RttNodeRef, Self::Error>;
217}
218
219impl<RT, S, F, NR, E> TransClosestToSample<RT, S> for F where F: FnOnce(&mut RT, &S) -> Result<NR, E> {
220 type RttNodeRef = NR;
221 type Error = E;
222
223 fn closest_to_sample(self, rtt: &mut RT, sample: &S) -> Result<Self::RttNodeRef, Self::Error> {
224 (self)(rtt, sample)
225 }
226}
227
228impl<RT, S> PlannerSample<RT, S> {
229 pub fn rtt(&self) -> &RT {
230 &self.rtt
231 }
232
233 pub fn sample(&self) -> &S {
234 &self.sample
235 }
236
237 pub fn closest_to_sample<TR>(mut self, trans: TR) ->
238 Result<PlannerClosestNodeFound<RT, TR::RttNodeRef, S>, TR::Error>
239 where TR: TransClosestToSample<RT, S>
240 {
241 let node_ref = trans.closest_to_sample(&mut self.rtt, &self.sample)?;
242 Ok(PlannerClosestNodeFound { rtt: self.rtt, node_ref, sample: self.sample, })
243 }
244
245 pub fn closest_to_sample_ok<TR>(self, trans: TR) -> PlannerClosestNodeFound<RT, TR::RttNodeRef, S>
246 where TR: TransClosestToSample<RT, S, Error = util::NeverError>
247 {
248 self.closest_to_sample(trans)
249 .unwrap_or_else(|_: util::NeverError| unreachable!())
250 }
251}
252
253pub struct PlannerClosestNodeFound<RT, NR, S> {
256 rtt: RT,
257 node_ref: NR,
258 sample: S,
259}
260
261pub trait TransNoTransition<RT, NR> {
262 type Error;
263
264 fn no_transition(self, rtt: &mut RT, node_ref: NR) -> Result<(), Self::Error>;
265}
266
267impl<RT, NR, F, E> TransNoTransition<RT, NR> for F where F: FnOnce(&mut RT, NR) -> Result<(), E> {
268 type Error = E;
269
270 fn no_transition(self, rtt: &mut RT, node_ref: NR) -> Result<(), Self::Error> {
271 (self)(rtt, node_ref)
272 }
273}
274
275pub trait TransHasTransition<RT, NR, S> {
276 type RttNodeRef;
277 type Error;
278
279 fn has_transition(self, rtt: &mut RT, node_ref: NR, sample: S) -> Result<Self::RttNodeRef, Self::Error>;
280}
281
282impl<RT, NR, S, F, NRO, E> TransHasTransition<RT, NR, S> for F where F: FnOnce(&mut RT, NR, S) -> Result<NRO, E> {
283 type RttNodeRef = NRO;
284 type Error = E;
285
286 fn has_transition(self, rtt: &mut RT, node_ref: NR, sample: S) -> Result<Self::RttNodeRef, Self::Error> {
287 (self)(rtt, node_ref, sample)
288 }
289}
290
291impl<RT, NR, S> PlannerClosestNodeFound<RT, NR, S> {
292 pub fn rtt(&self) -> &RT {
293 &self.rtt
294 }
295
296 pub fn node_ref(&self) -> &NR {
297 &self.node_ref
298 }
299
300 pub fn sample(&self) -> &S {
301 &self.sample
302 }
303
304 pub fn no_transition<TR>(mut self, trans: TR) -> Result<PlannerReadyToSample<RT>, TR::Error>
305 where TR: TransNoTransition<RT, NR>
306 {
307 let () = trans.no_transition(&mut self.rtt, self.node_ref)?;
308 Ok(PlannerReadyToSample { rtt: self.rtt, })
309 }
310
311 pub fn no_transition_ok<TR>(self, trans: TR) -> PlannerReadyToSample<RT>
312 where TR: TransNoTransition<RT, NR, Error = util::NeverError>
313 {
314 self.no_transition(trans)
315 .unwrap_or_else(|_: util::NeverError| unreachable!())
316 }
317
318 pub fn has_transition<TR>(mut self, trans: TR) -> Result<PlannerRttNode<RT, TR::RttNodeRef>, TR::Error>
319 where TR: TransHasTransition<RT, NR, S>
320 {
321 let node_ref = trans.has_transition(&mut self.rtt, self.node_ref, self.sample)?;
322 Ok(PlannerRttNode { rtt: self.rtt, node_ref, })
323 }
324
325 pub fn has_transition_ok<TR>(self, trans: TR) -> PlannerRttNode<RT, TR::RttNodeRef>
326 where TR: TransHasTransition<RT, NR, S, Error = util::NeverError>
327 {
328 self.has_transition(trans)
329 .unwrap_or_else(|_: util::NeverError| unreachable!())
330 }
331}
332
333#[cfg(test)]
334mod tests {
335 use super::*;
336
337 #[test]
338 fn skeleton() {
339
340 #[derive(PartialEq, Debug)]
341 enum Expect {
342 PlannerInit,
343 Planner,
344 PlannerRttNode,
345 PlannerReadyToSample(usize),
346 PlannerSample(usize),
347 PlannerClosestNodeFound(usize),
348 }
349
350 let planner = PlannerInit::new(Expect::PlannerInit);
351 let planner = planner.add_root_ok(|rtt| {
352 assert_eq!(rtt, Expect::PlannerInit);
353 Ok(Expect::Planner)
354 });
355
356 let mut planner_node = planner.root_node_ok(|rtt: &mut _| {
357 assert_eq!(rtt, &mut Expect::Planner);
358 *rtt = Expect::PlannerRttNode;
359 Ok(1)
360 });
361
362 let mut sample_counter = 0;
363 loop {
364 let expected_nodes_count = sample_counter / 2 + 1;
365 assert_eq!(planner_node.rtt(), &Expect::PlannerRttNode);
366 assert_eq!(planner_node.node_ref(), &expected_nodes_count);
367 if *planner_node.node_ref() >= 10 {
368 break;
369 }
370
371 let mut planner_ready_to_sample = planner_node.prepare_sample_ok(|rtt: &mut _, node_ref| {
372 assert_eq!(rtt, &mut Expect::PlannerRttNode);
373 *rtt = Expect::PlannerReadyToSample(node_ref);
374 Ok(())
375 });
376
377 loop {
378 let planner_sample = planner_ready_to_sample.sample_ok(|rtt: &mut _| {
379 assert_eq!(rtt, &mut Expect::PlannerReadyToSample(expected_nodes_count));
380 sample_counter += 1;
381 *rtt = Expect::PlannerSample(expected_nodes_count);
382 Ok(sample_counter)
383 });
384 assert_eq!(planner_sample.sample(), &sample_counter);
385
386 let planner_closest = planner_sample.closest_to_sample_ok(|rtt: &mut _, sample: &_| {
387 assert_eq!(rtt, &mut Expect::PlannerSample(expected_nodes_count));
388 assert_eq!(sample, &sample_counter);
389 *rtt = Expect::PlannerClosestNodeFound(expected_nodes_count);
390 Ok(expected_nodes_count)
391 });
392
393 if sample_counter % 2 == 0 {
394 planner_node = planner_closest.has_transition_ok(|rtt: &mut _, node_ref, sample| {
395 assert_eq!(rtt, &mut Expect::PlannerClosestNodeFound(expected_nodes_count));
396 assert_eq!(sample, sample_counter);
397 *rtt = Expect::PlannerRttNode;
398 Ok(node_ref + 1)
399 });
400 break;
401 } else {
402 planner_ready_to_sample = planner_closest.no_transition_ok(|rtt: &mut _, _node_ref| {
403 assert_eq!(rtt, &mut Expect::PlannerClosestNodeFound(expected_nodes_count));
404 *rtt = Expect::PlannerReadyToSample(expected_nodes_count);
405 Ok(())
406 });
407 }
408 }
409 }
410
411 let path = planner_node.into_path_ok(|rtt, node_ref| {
412 assert_eq!(rtt, Expect::PlannerRttNode);
413 Ok(node_ref)
414 });
415 assert_eq!(path, sample_counter / 2 + 1);
416 }
417}