Skip to main content

dshot_codec/
dshot_speed.rs

1use super::DshotError;
2
3#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
4pub enum DshotSpeed {
5    #[default]
6    Dshot150 = 0,
7    Dshot300 = 1,
8    Dshot600 = 2,
9    Dshot1200 = 3,
10}
11
12impl DshotSpeed {
13    #[must_use]
14    pub const fn baud_rate(self) -> u32 {
15        match self {
16            Self::Dshot150 => 150_000,
17            Self::Dshot300 => 300_000,
18            Self::Dshot600 => 600_000,
19            Self::Dshot1200 => 1_200_000,
20        }
21    }
22}
23
24impl TryFrom<u8> for DshotSpeed {
25    type Error = DshotError;
26
27    /// Validating conversion from `u8` to `Protocol`. Invalid values return error.
28    fn try_from(value: u8) -> Result<Self, DshotError> {
29        let default = Self::default();
30        if value == default as u8 {
31            Ok(default)
32        } else {
33            let ret = Self::from_u8(value);
34            if ret == default {
35                Err(DshotError::InvalidDshotSpeed)
36            } else {
37                Ok(ret)
38            }
39        }
40    }
41}
42
43impl DshotSpeed {
44    /// Forgiving conversion from `u8` to `Protocol`, converts invalid values to default.
45    #[must_use]
46    pub fn from_u8(value: u8) -> Self {
47        match value {
48            1 => Self::Dshot300,
49            2 => Self::Dshot600,
50            3 => Self::Dshot1200,
51            _ => Self::Dshot150,
52        }
53    }
54}
55
56#[cfg(test)]
57mod test_traits {
58    use super::*;
59
60    fn is_full_eq<T: Sized + Send + Sync + Unpin + Copy + Clone + Default + Eq + PartialEq>() {}
61
62    #[test]
63    fn normal_types() {
64        is_full_eq::<DshotSpeed>();
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71
72    #[test]
73    fn from_u8() {
74        // from_u8 is a forgiving conversion.
75        assert_eq!(DshotSpeed::from_u8(0), DshotSpeed::Dshot150);
76        assert_eq!(DshotSpeed::from_u8(1), DshotSpeed::Dshot300);
77        assert_eq!(DshotSpeed::from_u8(2), DshotSpeed::Dshot600);
78        assert_eq!(DshotSpeed::from_u8(3), DshotSpeed::Dshot1200);
79        assert_eq!(DshotSpeed::from_u8(4), DshotSpeed::Dshot150);
80        assert_eq!(DshotSpeed::from_u8(255), DshotSpeed::Dshot150);
81    }
82    #[test]
83    fn try_from_() {
84        // With try_from invalid values give error.
85        assert_eq!(DshotSpeed::try_from(0), Ok(DshotSpeed::Dshot150));
86        assert_eq!(DshotSpeed::try_from(1), Ok(DshotSpeed::Dshot300));
87        assert_eq!(DshotSpeed::try_from(2), Ok(DshotSpeed::Dshot600));
88        assert_eq!(DshotSpeed::try_from(3), Ok(DshotSpeed::Dshot1200));
89        assert_eq!(DshotSpeed::try_from(4), Err(DshotError::InvalidDshotSpeed));
90        assert_eq!(DshotSpeed::try_from(255), Err(DshotError::InvalidDshotSpeed));
91    }
92    #[test]
93    fn baud_rates() {
94        assert_eq!(DshotSpeed::Dshot150.baud_rate(), 150_000);
95        assert_eq!(DshotSpeed::Dshot300.baud_rate(), 300_000);
96        assert_eq!(DshotSpeed::Dshot600.baud_rate(), 600_000);
97        assert_eq!(DshotSpeed::Dshot1200.baud_rate(), 1_200_000);
98    }
99}