1use crate::{
2 bindings,
3 error::{get_errno, Error},
4 prelude::DataSource,
5};
6
7pub struct AdiDigitalInput {
9 port: u8,
10 expander_port: u8,
11}
12
13impl AdiDigitalInput {
14 pub unsafe fn new(port: u8, expander_port: u8) -> Result<Self, AdiDigitalInputError> {
22 match bindings::ext_adi_port_set_config(
23 expander_port,
24 port,
25 bindings::adi_port_config_e_E_ADI_DIGITAL_IN,
26 ) {
27 bindings::PROS_ERR_ => Err(AdiDigitalInputError::from_errno()),
28 _ => Ok(Self {
29 port,
30 expander_port,
31 }),
32 }
33 }
34
35 pub fn read(&self) -> Result<bool, AdiDigitalInputError> {
37 match unsafe { bindings::ext_adi_digital_read(self.expander_port, self.port) } {
38 bindings::PROS_ERR_ => Err(AdiDigitalInputError::from_errno()),
39 0 => Ok(false),
40 _ => Ok(true),
41 }
42 }
43}
44
45impl DataSource for AdiDigitalInput {
46 type Data = bool;
47
48 type Error = AdiDigitalInputError;
49
50 fn read(&self) -> Result<Self::Data, Self::Error> {
51 self.read()
52 }
53}
54
55#[derive(Debug)]
57pub enum AdiDigitalInputError {
58 PortsOutOfRange,
60 PortsNotDigitalInput,
62 Unknown(i32),
64}
65
66impl AdiDigitalInputError {
67 fn from_errno() -> Self {
68 match get_errno() {
69 libc::ENXIO => Self::PortsOutOfRange,
70 libc::EADDRINUSE => Self::PortsNotDigitalInput,
71 x => Self::Unknown(x),
72 }
73 }
74}
75
76impl From<AdiDigitalInputError> for Error {
77 fn from(err: AdiDigitalInputError) -> Self {
78 match err {
79 AdiDigitalInputError::PortsOutOfRange => Error::Custom("port is out of range".into()),
80 AdiDigitalInputError::PortsNotDigitalInput => {
81 Error::Custom("port is not an ADI digital input".into())
82 }
83 AdiDigitalInputError::Unknown(n) => Error::System(n),
84 }
85 }
86}