use crate::master::core::EtherCATMaster;
use crate::slave::core::Slave;
use std::cell::UnsafeCell;
use std::ops::Index;
pub struct Indexable<'a> {
master: &'a EtherCATMaster,
cache: UnsafeCell<Vec<Slave>>,
}
impl<'a> Indexable<'a> {
pub(crate) fn new(master: &'a EtherCATMaster) -> Self {
let count = master.slave_count() as usize;
let mi = master.index();
let mut v = Vec::with_capacity(count + 1);
for i in 0..=count {
v.push(Slave::new(mi, i as u16));
}
Self {
master,
cache: UnsafeCell::new(v),
}
}
pub fn len(&self) -> usize {
self.master.slave_count() as usize
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl<'a> Index<usize> for Indexable<'a> {
type Output = Slave;
fn index(&self, idx: usize) -> &Self::Output {
let v = unsafe { &*self.cache.get() };
&v[idx]
}
}
impl<'a> Index<u16> for Indexable<'a> {
type Output = Slave;
fn index(&self, idx: u16) -> &Self::Output {
let v = unsafe { &*self.cache.get() };
&v[idx as usize]
}
}
pub trait MasterIndexExt {
fn indexable(&self) -> Indexable<'_>;
}
impl MasterIndexExt for EtherCATMaster {
fn indexable(&self) -> Indexable<'_> {
Indexable::new(self)
}
}