1use crate::{
4 bindings,
5 error::{get_errno, Error},
6 rtos::DataSource,
7};
8
9pub struct DistanceSensor {
11 port: u8,
12}
13
14impl DistanceSensor {
15 pub unsafe fn new(port: u8) -> DistanceSensor {
23 DistanceSensor { port }
24 }
25
26 pub fn get_distance(&self) -> Result<i32, DistanceSensorError> {
28 match unsafe { bindings::distance_get(self.port) } {
29 x if x == bindings::PROS_ERR_ => Err(DistanceSensorError::from_errno()),
30 x => Ok(x),
31 }
32 }
33
34 pub fn get_confidence(&self) -> Result<i32, DistanceSensorError> {
40 match unsafe { bindings::distance_get_confidence(self.port) } {
41 x if x == bindings::PROS_ERR_ => Err(DistanceSensorError::from_errno()),
42 x => Ok(x),
43 }
44 }
45
46 pub fn get_object_size(&self) -> Result<i32, DistanceSensorError> {
51 match unsafe { bindings::distance_get_object_size(self.port) } {
52 x if x == bindings::PROS_ERR_ => Err(DistanceSensorError::from_errno()),
53 x => Ok(x),
54 }
55 }
56
57 pub fn get_object_velocity(&self) -> Result<f64, DistanceSensorError> {
59 match unsafe { bindings::distance_get_object_velocity(self.port) } {
60 x if x == bindings::PROS_ERR_F_ => Err(DistanceSensorError::from_errno()),
61 x => Ok(x),
62 }
63 }
64}
65
66impl DataSource for DistanceSensor {
67 type Data = DistanceData;
68
69 type Error = DistanceSensorError;
70
71 fn read(&self) -> Result<Self::Data, Self::Error> {
72 Ok(DistanceData {
73 confidence: self.get_confidence()?,
74 size: self.get_object_size()?,
75 velocity: self.get_object_velocity()?,
76 })
77 }
78}
79
80#[derive(Clone, Copy, Debug, PartialEq)]
82pub struct DistanceData {
83 pub confidence: i32,
85 pub size: i32,
87 pub velocity: f64,
89}
90
91#[derive(Debug)]
93pub enum DistanceSensorError {
94 PortOutOfRange,
96 PortNotDistanceSensor,
98 Unknown(i32),
100}
101
102impl DistanceSensorError {
103 fn from_errno() -> Self {
104 match get_errno() {
105 libc::ENXIO => Self::PortOutOfRange,
106 libc::ENODEV => Self::PortNotDistanceSensor,
107 x => Self::Unknown(x),
108 }
109 }
110}
111
112impl From<DistanceSensorError> for Error {
113 fn from(err: DistanceSensorError) -> Self {
114 match err {
115 DistanceSensorError::PortOutOfRange => Error::Custom("port out of range".into()),
116 DistanceSensorError::PortNotDistanceSensor => {
117 Error::Custom("port not a distance sensor".into())
118 }
119 DistanceSensorError::Unknown(n) => Error::System(n),
120 }
121 }
122}