1use core::marker::PhantomData;
2
3use crate::FieldSet;
4
5pub trait CommandInterface {
9 type Error;
11 type AddressType: Copy;
13
14 fn dispatch_command(
21 &mut self,
22 address: Self::AddressType,
23 size_bits_in: u32,
24 input: &[u8],
25 size_bits_out: u32,
26 output: &mut [u8],
27 ) -> Result<(), Self::Error>;
28}
29
30pub trait AsyncCommandInterface {
34 type Error;
36 type AddressType: Copy;
38
39 async fn dispatch_command(
46 &mut self,
47 address: Self::AddressType,
48 size_bits_in: u32,
49 input: &[u8],
50 size_bits_out: u32,
51 output: &mut [u8],
52 ) -> Result<(), Self::Error>;
53}
54
55pub struct CommandOperation<'i, Interface, AddressType: Copy, InFieldSet, OutFieldSet> {
57 interface: &'i mut Interface,
58 address: AddressType,
59 _phantom: PhantomData<(InFieldSet, OutFieldSet)>,
60}
61
62impl<'i, Interface, AddressType: Copy, InFieldSet, OutFieldSet>
63 CommandOperation<'i, Interface, AddressType, InFieldSet, OutFieldSet>
64{
65 #[doc(hidden)]
66 pub fn new(interface: &'i mut Interface, address: AddressType) -> Self {
67 Self {
68 interface,
69 address,
70 _phantom: PhantomData,
71 }
72 }
73}
74
75impl<Interface, AddressType: Copy> CommandOperation<'_, Interface, AddressType, (), ()>
77where
78 Interface: CommandInterface<AddressType = AddressType>,
79{
80 pub fn dispatch(self) -> Result<(), Interface::Error> {
82 self.interface
83 .dispatch_command(self.address, 0, &[], 0, &mut [])
84 }
85}
86
87impl<Interface, AddressType: Copy, InFieldSet: FieldSet>
89 CommandOperation<'_, Interface, AddressType, InFieldSet, ()>
90where
91 Interface: CommandInterface<AddressType = AddressType>,
92{
93 pub fn dispatch(self, f: impl FnOnce(&mut InFieldSet)) -> Result<(), Interface::Error> {
95 let mut in_fields = InFieldSet::new_with_zero();
96 f(&mut in_fields);
97
98 self.interface.dispatch_command(
99 self.address,
100 InFieldSet::SIZE_BITS,
101 in_fields.get_inner_buffer(),
102 0,
103 &mut [],
104 )
105 }
106}
107
108impl<Interface, AddressType: Copy, OutFieldSet: FieldSet>
110 CommandOperation<'_, Interface, AddressType, (), OutFieldSet>
111where
112 Interface: CommandInterface<AddressType = AddressType>,
113{
114 pub fn dispatch(self) -> Result<OutFieldSet, Interface::Error> {
116 let mut out_fields = OutFieldSet::new_with_zero();
117
118 self.interface.dispatch_command(
119 self.address,
120 0,
121 &[],
122 OutFieldSet::SIZE_BITS,
123 out_fields.get_inner_buffer_mut(),
124 )?;
125
126 Ok(out_fields)
127 }
128}
129
130impl<Interface, AddressType: Copy, InFieldSet: FieldSet, OutFieldSet: FieldSet>
132 CommandOperation<'_, Interface, AddressType, InFieldSet, OutFieldSet>
133where
134 Interface: CommandInterface<AddressType = AddressType>,
135{
136 pub fn dispatch(
138 self,
139 f: impl FnOnce(&mut InFieldSet),
140 ) -> Result<OutFieldSet, Interface::Error> {
141 let mut in_fields = InFieldSet::new_with_zero();
142 f(&mut in_fields);
143
144 let mut out_fields = OutFieldSet::new_with_zero();
145
146 self.interface.dispatch_command(
147 self.address,
148 InFieldSet::SIZE_BITS,
149 in_fields.get_inner_buffer(),
150 OutFieldSet::SIZE_BITS,
151 out_fields.get_inner_buffer_mut(),
152 )?;
153
154 Ok(out_fields)
155 }
156}
157
158impl<Interface, AddressType: Copy> CommandOperation<'_, Interface, AddressType, (), ()>
160where
161 Interface: AsyncCommandInterface<AddressType = AddressType>,
162{
163 pub async fn dispatch_async(self) -> Result<(), Interface::Error> {
165 self.interface
166 .dispatch_command(self.address, 0, &[], 0, &mut [])
167 .await
168 }
169}
170
171impl<Interface, AddressType: Copy, InFieldSet: FieldSet>
173 CommandOperation<'_, Interface, AddressType, InFieldSet, ()>
174where
175 Interface: AsyncCommandInterface<AddressType = AddressType>,
176{
177 pub async fn dispatch_async(
179 self,
180 f: impl FnOnce(&mut InFieldSet),
181 ) -> Result<(), Interface::Error> {
182 let mut in_fields = InFieldSet::new_with_zero();
183 f(&mut in_fields);
184
185 self.interface
186 .dispatch_command(
187 self.address,
188 InFieldSet::SIZE_BITS,
189 in_fields.get_inner_buffer(),
190 0,
191 &mut [],
192 )
193 .await
194 }
195}
196
197impl<Interface, AddressType: Copy, OutFieldSet: FieldSet>
199 CommandOperation<'_, Interface, AddressType, (), OutFieldSet>
200where
201 Interface: AsyncCommandInterface<AddressType = AddressType>,
202{
203 pub async fn dispatch_async(self) -> Result<OutFieldSet, Interface::Error> {
205 let mut out_fields = OutFieldSet::new_with_zero();
206
207 self.interface
208 .dispatch_command(
209 self.address,
210 0,
211 &[],
212 OutFieldSet::SIZE_BITS,
213 out_fields.get_inner_buffer_mut(),
214 )
215 .await?;
216
217 Ok(out_fields)
218 }
219}
220
221impl<Interface, AddressType: Copy, InFieldSet: FieldSet, OutFieldSet: FieldSet>
223 CommandOperation<'_, Interface, AddressType, InFieldSet, OutFieldSet>
224where
225 Interface: AsyncCommandInterface<AddressType = AddressType>,
226{
227 pub async fn dispatch_async(
229 self,
230 f: impl FnOnce(&mut InFieldSet),
231 ) -> Result<OutFieldSet, Interface::Error> {
232 let mut in_fields = InFieldSet::new_with_zero();
233 f(&mut in_fields);
234
235 let mut out_fields = OutFieldSet::new_with_zero();
236
237 self.interface
238 .dispatch_command(
239 self.address,
240 InFieldSet::SIZE_BITS,
241 in_fields.get_inner_buffer(),
242 OutFieldSet::SIZE_BITS,
243 out_fields.get_inner_buffer_mut(),
244 )
245 .await?;
246
247 Ok(out_fields)
248 }
249}