sysfuss 0.3.0

sysfs wrapper for convenience
Documentation
//! sysfs class entity capability filtering

mod all;
mod any;
mod attributes;

use all::AllCapabilities;
use any::AnyCapabilities;
use attributes::AttributeCapabilities;

/// Capabilities filter
pub trait Capabilities<A: crate::SysAttribute, E: crate::SysEntityAttributes<A> + ?Sized> {
    /// Are the required capabilities (self) satisfied by the provided capabilities (the parameter)?
    fn satisfies(&mut self, entity: &E) -> bool;
}

impl <F: FnMut(&E) -> bool, A: crate::SysAttribute, E: crate::SysEntityAttributes<A> + ?Sized> Capabilities<A, E> for F {
    fn satisfies(&mut self, entity: &E) -> bool {
        (self)(entity)
    }
}

/// Build a Capabilities implementor which needs specific attributes to exist
pub fn attributes<A: crate::SysAttribute, E: crate::SysEntityAttributes<A> + ?Sized>(iter: impl Iterator<Item=A>) -> impl Capabilities<A, E> {
    AttributeCapabilities {
        required: iter.collect(),
        _entity_ty: Default::default(),
    }
}

/// Chain two capabilities requirements together such that the new capabilities are only satisfied when both inner capabilities are satisfied
pub fn and<'a, A: crate::SysAttribute + 'a, E: crate::SysEntityAttributes<A> + ?Sized + 'a>(mut first: impl Capabilities<A, E> + 'a, mut second: impl Capabilities<A, E> + 'a) -> impl Capabilities<A, E> + 'a {
    AllCapabilities {
        required: vec![
            Box::new(move |ent: &E| first.satisfies(ent)) as Box<dyn FnMut(&E) -> bool>,
            Box::new(move |ent: &E| second.satisfies(ent)) as Box<dyn FnMut(&E) -> bool>,
        ],
        _attr_ty: Default::default(),
        _entity_ty: Default::default(),
    }
}

/// Chain two capabilities requirements together such that the new capabilities are satisfied when either of the inner capabilities is satisfied
pub fn or<'a, A: crate::SysAttribute + 'a, E: crate::SysEntityAttributes<A> + ?Sized + 'a>(mut first: impl Capabilities<A, E> + 'a, mut second: impl Capabilities<A, E> + 'a) -> impl Capabilities<A, E> + 'a {
    AnyCapabilities {
        required: vec![
            Box::new(move |ent: &E| first.satisfies(ent)) as Box<dyn FnMut(&E) -> bool>,
            Box::new(move |ent: &E| second.satisfies(ent)) as Box<dyn FnMut(&E) -> bool>,
        ],
        _attr_ty: Default::default(),
        _entity_ty: Default::default(),
    }
}