Skip to main content

autd3_rs/
response.rs

1use crate::client::MAX_DEVICES;
2use crate::error::Error;
3
4#[derive(Clone, Copy, Debug, PartialEq, Eq)]
5pub struct Response {
6    data: [u8; MAX_DEVICES],
7    len: usize,
8}
9
10impl Default for Response {
11    fn default() -> Self {
12        Self {
13            data: [0; MAX_DEVICES],
14            len: 0,
15        }
16    }
17}
18
19impl Response {
20    #[must_use]
21    pub fn from_slice(data: &[u8]) -> Self {
22        let len = data.len().min(MAX_DEVICES);
23        let mut buf = [0u8; MAX_DEVICES];
24        buf[..len].copy_from_slice(&data[..len]);
25        Self { data: buf, len }
26    }
27
28    #[must_use]
29    pub fn data(&self) -> &[u8] {
30        &self.data[..self.len]
31    }
32
33    pub fn merge(&mut self, other: &Response) {
34        self.data[..self.len]
35            .iter_mut()
36            .zip(other.data().iter().copied())
37            .for_each(|(m, d)| {
38                if *m == 0 {
39                    *m = d;
40                }
41            });
42    }
43
44    pub fn check(&self) -> Result<(), Error> {
45        match self.data().iter().enumerate().find(|&(_, &d)| d != 0) {
46            None => Ok(()),
47            Some((device, &code)) => Err(Error::DeviceError { device, code }),
48        }
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::Response;
55
56    #[test]
57    fn data_exposes_only_the_recorded_devices() {
58        assert_eq!(Response::from_slice(&[0x00, 0xAB]).data(), [0x00, 0xAB]);
59        assert!(Response::from_slice(&[]).data().is_empty());
60    }
61
62    #[test]
63    fn from_slice_clamps_to_the_device_limit() {
64        let response = Response::from_slice(&[1u8; crate::client::MAX_DEVICES + 4]);
65        assert_eq!(response.data().len(), crate::client::MAX_DEVICES);
66    }
67
68    #[test]
69    fn check_reports_the_first_nonzero_device() {
70        assert!(Response::from_slice(&[0, 0, 0]).check().is_ok());
71        let err = Response::from_slice(&[0, 0x07, 0x09]).check().unwrap_err();
72        assert!(matches!(
73            err,
74            crate::error::Error::DeviceError {
75                device: 1,
76                code: 0x07
77            }
78        ));
79    }
80}