use super::{info::ChainInfo, Axis, Device};
use std::num::NonZeroU8;
pub struct IterDevices<'a, Tag> {
info: &'a ChainInfo,
next_index: usize,
tag: std::marker::PhantomData<Tag>,
}
impl<'a, Tag> IterDevices<'a, Tag> {
pub(super) fn new(info: &'a ChainInfo) -> Self {
IterDevices {
info,
next_index: 0,
tag: std::marker::PhantomData,
}
}
}
impl<Tag> std::fmt::Debug for IterDevices<'_, Tag> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("IterDevices").finish_non_exhaustive()
}
}
impl<'a, Tag> std::iter::Iterator for IterDevices<'a, Tag> {
type Item = Device<'a, Tag>;
fn next(&mut self) -> Option<Self::Item> {
let address = self
.info
.devices
.values()
.nth(self.next_index)
.map(|device_info| device_info.address);
if let Some(address) = address {
self.next_index += 1;
Some(Device::new(self.info, address))
} else {
None
}
}
}
pub struct IterAxes<'a, Tag> {
info: &'a ChainInfo,
address: NonZeroU8,
next_axis_index: usize,
tag: std::marker::PhantomData<Tag>,
}
impl<'a, Tag> IterAxes<'a, Tag> {
pub(super) fn new(info: &'a ChainInfo, address: NonZeroU8) -> Self {
IterAxes {
info,
address,
next_axis_index: 0,
tag: std::marker::PhantomData,
}
}
}
impl<'a, Tag> std::iter::Iterator for IterAxes<'a, Tag> {
type Item = Axis<'a, Tag>;
fn next(&mut self) -> Option<Self::Item> {
#![allow(clippy::cast_possible_truncation)]
assert!(self.next_axis_index < u8::MAX as usize - 1);
let axis_number = self
.info
.devices
.get(&self.address)
.and_then(|device_info| {
if self.next_axis_index < device_info.axes.len() {
Some(NonZeroU8::new(self.next_axis_index as u8 + 1).unwrap())
} else {
None
}
});
if let Some(axis_number) = axis_number {
self.next_axis_index += 1;
Some(Axis::new(self.info, self.address, axis_number))
} else {
None
}
}
}
impl<Tag> std::fmt::Debug for IterAxes<'_, Tag> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("IterAxes")
.field("address", &self.address)
.finish()
}
}
#[derive(Debug)]
pub struct IntoIterAxes<'a, Tag> {
iter: IterAxes<'a, Tag>,
}
impl<'a, Tag> IntoIterAxes<'a, Tag> {
pub(super) fn new(info: &'a ChainInfo, address: NonZeroU8) -> Self {
IntoIterAxes {
iter: IterAxes::new(info, address),
}
}
}
impl<'a, Tag> std::iter::Iterator for IntoIterAxes<'a, Tag> {
type Item = Axis<'a, Tag>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
}