1use core::time::Duration;
2use void::Void;
3
4pub trait Device {
6 type Error;
10
11 fn step(&mut self, ctx: &StepContext) -> Result<(), Self::Error>;
12}
13
14impl<'a, D: Device> Device for &'a mut D {
15 type Error = D::Error;
16
17 fn step(&mut self, ctx: &StepContext) -> Result<(), Self::Error> {
18 (*self).step(ctx)
19 }
20}
21
22#[derive(Debug, Clone, PartialEq)]
25pub struct StepContext {
26 pub position: i64,
28 pub step_time: Duration,
31}
32
33pub fn func_device<F, B, T>(
39 forward: F,
40 backward: B,
41) -> impl Device<Error = Void>
42where
43 F: FnMut() -> T,
44 B: FnMut() -> T,
45{
46 Infallible {
47 forward,
48 backward,
49 previous_position: 0,
50 }
51}
52
53struct Infallible<F, B> {
54 previous_position: i64,
55 forward: F,
56 backward: B,
57}
58
59impl<F, B, T> Device for Infallible<F, B>
60where
61 F: FnMut() -> T,
62 B: FnMut() -> T,
63{
64 type Error = Void;
65
66 #[inline]
67 fn step(&mut self, ctx: &StepContext) -> Result<(), Self::Error> {
68 let diff = ctx.position - self.previous_position;
69
70 if diff > 0 {
71 (self.forward)();
72 } else if diff < 0 {
73 (self.backward)();
74 }
75
76 self.previous_position = ctx.position;
77 Ok(())
78 }
79}
80
81pub fn fallible_func_device<F, B, T, E>(
85 forward: F,
86 backward: B,
87) -> impl Device<Error = E>
88where
89 F: FnMut() -> Result<T, E>,
90 B: FnMut() -> Result<T, E>,
91{
92 Fallible {
93 forward,
94 backward,
95 previous_position: 0,
96 }
97}
98
99struct Fallible<F, B> {
100 previous_position: i64,
101 forward: F,
102 backward: B,
103}
104
105impl<F, B, T, E> Device for Fallible<F, B>
106where
107 F: FnMut() -> Result<T, E>,
108 B: FnMut() -> Result<T, E>,
109{
110 type Error = E;
111
112 #[inline]
113 fn step(&mut self, ctx: &StepContext) -> Result<(), Self::Error> {
114 let diff = ctx.position - self.previous_position;
115
116 if diff > 0 {
117 (self.forward)()?;
118 } else if diff < 0 {
119 (self.backward)()?;
120 }
121
122 self.previous_position = ctx.position;
123 Ok(())
124 }
125}