use crate::data::error::{DarraError, EcState, Result};
use crate::master::core::EtherCATMaster;
use crate::slave::core::Slave;
pub trait MasterTrySlaveExt {
fn try_slave(&self, slave_index: u16) -> Result<Slave>;
fn slave_opt(&self, slave_index: u16) -> Option<Slave>;
}
impl MasterTrySlaveExt for EtherCATMaster {
fn try_slave(&self, slave_index: u16) -> Result<Slave> {
if slave_index == 0 {
return Err(DarraError::InvalidParameter(
"从站索引必须 >= 1 (0 表示主站本身)".into(),
));
}
let count = self.slave_count();
if slave_index > count {
return Err(DarraError::InvalidParameter(format!(
"从站索引 {} 越界 (实际从站数 = {})",
slave_index, count
)));
}
Ok(self.slave(slave_index))
}
fn slave_opt(&self, slave_index: u16) -> Option<Slave> {
let count = self.slave_count();
if slave_index >= 1 && slave_index <= count {
Some(self.slave(slave_index))
} else {
None
}
}
}
pub trait MasterStateTryExt {
fn try_set_state(&self, target: EcState, timeout_ms: u32) -> Result<()>;
}
impl MasterStateTryExt for EtherCATMaster {
fn try_set_state(&self, target: EcState, timeout_ms: u32) -> Result<()> {
use crate::utils::ffi;
use std::os::raw::c_int;
let mi = self.index();
let ok = unsafe { ffi::SetStateWithTimeout(mi, target as c_int, timeout_ms) } != 0;
if ok { Ok(()) } else { Err(DarraError::StateChangeFailed(target as u8)) }
}
}