darra-ethercat-master 2.0.1

商业 EtherCAT 主站协议栈 · 实时内核驱动 · 抖动 1µs · Windows + Linux · 多编程语言 · 全协议 · 支持复杂拓扑 + 热插拔 · ethercat.darra.xyz · Commercial EtherCAT Master protocol stack · Real-time kernel driver · 1µs jitter · Multi-platform · Multi-language · Complex topology + hot-plug.
//! 迭代器扩展: 在 [`crate::SlaveIterator`] 之上叠加链式过滤
//!
//! SDK 已经为 `EtherCATMaster` 实现了 `IntoIterator`, 调用 `master.iter()`
//! 或 `for s in &master` 都能拿到 [`crate::Slave`] 流. 本模块给 `Iterator<Item=Slave>`
//! 增加几个领域感知的过滤适配器, 让常见的"按状态/组/厂商筛选"写法变得一行:
//!
//! ```no_run
//! use darra_ethercat::sugar::prelude::*;
//! use darra_ethercat::{EtherCATMaster, EcState};
//!
//! let m = EtherCATMaster::new().unwrap();
//!
//! // 按状态过滤
//! let op_count = m.iter().by_state(EcState::Operational).count();
//!
//! // 按组过滤 + 按厂商过滤 + 收集
//! let beckhoff_g0: Vec<_> = m.iter()
//!     .by_group(0)
//!     .by_vendor(0x00000002)   // Beckhoff
//!     .collect();
//!
//! // 任意复合谓词 (利用 detailed_info 拿 AL Status Code)
//! let buggy: Vec<_> = m.iter()
//!     .filter_slave(|s| s.detailed_info().map(|d| d.al_status_code != 0).unwrap_or(false))
//!     .collect();
//! ```

use crate::data::error::EcState;
use crate::slave::core::Slave;

/// 给 `Iterator<Item = Slave>` 加领域感知方法的扩展 trait.
pub trait SlaveIterExt: Iterator<Item = Slave> + Sized {
    /// 按 EtherCAT 状态过滤
    fn by_state(self, state: EcState) -> ByState<Self> {
        ByState { inner: self, target: state }
    }

    /// 按组编号过滤 (0..=7)
    fn by_group(self, group: u8) -> ByGroup<Self> {
        ByGroup { inner: self, group }
    }

    /// 按厂商 ID 过滤
    fn by_vendor(self, vendor_id: u32) -> ByVendor<Self> {
        ByVendor { inner: self, vendor_id }
    }

    /// 任意自定义谓词 (语义上等价 `Iterator::filter`, 但签名更明确为 `&Slave -> bool`)
    fn filter_slave<F: FnMut(&Slave) -> bool>(self, pred: F) -> FilterSlave<Self, F> {
        FilterSlave { inner: self, pred }
    }

    /// 仅保留有 DC 同步能力的从站
    fn with_dc(self) -> WithDc<Self> {
        WithDc { inner: self }
    }
}

impl<I: Iterator<Item = Slave>> SlaveIterExt for I {}

// ============================================================
// 适配器: ByState
// ============================================================

pub struct ByState<I> {
    inner: I,
    target: EcState,
}

impl<I: Iterator<Item = Slave>> Iterator for ByState<I> {
    type Item = Slave;
    fn next(&mut self) -> Option<Self::Item> {
        let target = self.target;
        self.inner.find(|s| s.state().map(|st| st == target).unwrap_or(false))
    }
}

// ============================================================
// 适配器: ByGroup
// ============================================================

pub struct ByGroup<I> {
    inner: I,
    group: u8,
}

impl<I: Iterator<Item = Slave>> Iterator for ByGroup<I> {
    type Item = Slave;
    fn next(&mut self) -> Option<Self::Item> {
        let g = self.group;
        self.inner.find(|s| s.group() == g)
    }
}

// ============================================================
// 适配器: ByVendor
// ============================================================

pub struct ByVendor<I> {
    inner: I,
    vendor_id: u32,
}

impl<I: Iterator<Item = Slave>> Iterator for ByVendor<I> {
    type Item = Slave;
    fn next(&mut self) -> Option<Self::Item> {
        let v = self.vendor_id;
        self.inner.find(|s| s.vendor_id() == v)
    }
}

// ============================================================
// 适配器: FilterSlave (自定义谓词)
// ============================================================

pub struct FilterSlave<I, F> {
    inner: I,
    pred: F,
}

impl<I, F> Iterator for FilterSlave<I, F>
where
    I: Iterator<Item = Slave>,
    F: FnMut(&Slave) -> bool,
{
    type Item = Slave;
    fn next(&mut self) -> Option<Self::Item> {
        let pred = &mut self.pred;
        self.inner.find(|s| pred(s))
    }
}

// ============================================================
// 适配器: WithDc
// ============================================================

pub struct WithDc<I> {
    inner: I,
}

impl<I: Iterator<Item = Slave>> Iterator for WithDc<I> {
    type Item = Slave;
    fn next(&mut self) -> Option<Self::Item> {
        self.inner.find(|s| {
            // SDK 提供的 has_dc 语义: 检查从站是否上报 DC 能力.
            // 没有该方法时退化到 detailed_info.hasdc != 0
            s.detailed_info().map(|info| info.hasdc != 0).unwrap_or(false)
        })
    }
}