1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
macro_rules! impl_pin { ($type:ident, $type_str:expr, $hal_fn:expr, $hal_fn_str:expr, $storage:ty, $storage_str:expr) => { #[doc = $type_str] #[doc = "HAL pin."] #[doc = ""] #[doc = "Equivalent to the [`"] #[doc = $hal_fn_str] #[doc = "`] HAL function, backed internally by a [`"] #[doc = $storage_str] #[doc = "`]."] #[derive(Debug, PartialEq)] pub struct $type { name: String, storage: *mut *mut $storage, } impl $crate::hal_pin::HalPin for $type { type Storage = $storage; fn name(&self) -> &str { &self.name } fn storage(&self) -> Result<&mut Self::Storage, $crate::error::StorageError> { if self.storage.is_null() { Err($crate::error::StorageError::Null) } else { Ok(unsafe { &mut **self.storage }) } } fn register_pin( full_pin_name: &str, direction: $crate::hal_pin::PinDirection, component_id: i32, ) -> Result<Self, $crate::error::PinRegisterError> { if full_pin_name.len() > linuxcnc_hal_sys::HAL_NAME_LEN as usize { return Err($crate::error::PinRegisterError::NameLength); } let storage = Self::allocate_storage().map_err($crate::error::PinRegisterError::Storage)?; let ret = unsafe { $hal_fn( full_pin_name.as_ptr() as *const i8, direction as i32, storage as *mut *mut $storage, component_id, ) }; match ret { x if x == -(linuxcnc_hal_sys::EINVAL as i32) => { Err($crate::error::PinRegisterError::Invalid) } x if x == -(linuxcnc_hal_sys::EPERM as i32) => Err($crate::error::PinRegisterError::LockedHal), x if x == -(linuxcnc_hal_sys::ENOMEM as i32) => { Err($crate::error::PinRegisterError::Memory) } 0 => { debug!("Make pin {} returned {}", full_pin_name, ret); Ok(Self { name: full_pin_name.to_string(), storage, }) } code => unreachable!("Hit unreachable error code {}", code), } } } impl Drop for $type { fn drop(&mut self) { debug!("Drop HalPinF64 {}", self.name); } } }; }