From 65eae75c3a98211849c1297c1ccdd523f39bab6a Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Sun, 6 Aug 2023 14:50:34 -0400 Subject: [PATCH] Add more capability functionality and improve API --- src/attribute.rs | 2 +- src/capability.rs | 35 +++++++++++++++++++++++++++++++++++ src/entity.rs | 17 +++++++++++++++++ src/hwmon.rs | 5 ++++- src/lib.rs | 2 +- 5 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/attribute.rs b/src/attribute.rs index a1967db..a3a3dcb 100644 --- a/src/attribute.rs +++ b/src/attribute.rs @@ -63,7 +63,7 @@ pub trait SysAttributeExt: SysAttribute + Eq { /// read and parse the attribute value fn parse, E>(&self, entity: &dyn crate::SysEntity) -> Result> { let s = self.read_str(entity).map_err(EitherErr2::First)?; - T::from_str(&s).map_err(EitherErr2::Second) + T::from_str(s.trim_end_matches('\n')).map_err(EitherErr2::Second) } } diff --git a/src/capability.rs b/src/capability.rs index 4dc74d1..1363b24 100644 --- a/src/capability.rs +++ b/src/capability.rs @@ -19,6 +19,12 @@ pub fn attributes<'a, A: crate::SysAttribute + Eq + 'a, R: std::borrow::Borrow + 'a, F: (FnMut(&R) -> bool) + 'a>(requirements: impl Iterator) -> impl Capabilities + 'a { + AllNeedsCapabilities::new( + requirements.collect() + ) +} struct AllNeedsCapabilities<'a, 'f, A: crate::SysAttribute + 'a, R: std::borrow::Borrow + 'a, F: (FnMut(&R) -> bool) + 'f> { wanted: Vec, @@ -51,3 +57,32 @@ impl <'a, 'f, A: crate::SysAttribute + 'a, R: std::borrow::Borrow + 'a, F: (F wants.into_iter().all(|item| item) } } + +/// Chain two capabilities requirements together such that the new capabilities are only satisfied when both inner capabilities are satisfied +pub fn and>(first: impl Capabilities, second: impl Capabilities) -> impl Capabilities { + ChainCapabilities::new(first, second) +} + +struct ChainCapabilities, X: Capabilities, Y: Capabilities> { + first: X, + second: Y, + _attr_ty: std::marker::PhantomData, + _attr_brw_ty: std::marker::PhantomData, +} + +impl , X: Capabilities, Y: Capabilities> ChainCapabilities { + pub(crate) fn new(first: X, second: Y) -> Self { + Self { + first, + second, + _attr_ty: Default::default(), + _attr_brw_ty: Default::default(), + } + } +} + +impl , X: Capabilities, Y: Capabilities> Capabilities for ChainCapabilities { + fn can(&mut self, capabilities: &Vec) -> bool { + self.first.can(capabilities) && self.second.can(capabilities) + } +} diff --git a/src/entity.rs b/src/entity.rs index 40f3041..59cb380 100644 --- a/src/entity.rs +++ b/src/entity.rs @@ -72,9 +72,21 @@ impl SysEntityRawExt for X { pub trait SysEntityAttributes: SysEntity + Sized { /// Get attributes available on this entity; fn capabilities(&self) -> Vec; + + /// Read entity attribute value + fn read_value(&self, attr: A) -> IoResult> { + attr.read_value(self) + } + + /// Write entity attribute value + fn write_value(&self, attr: A, value: &[u8]) -> IoResult<()> { + attr.write_value(self, value) + } } +/// sysfs class entity attribute type extension pub trait SysEntityAttributesExt: SysEntityAttributes { + /// Returns true if self is capable of the provided capabilities fn capable>(&self, mut capabilities: C) -> bool { capabilities.can(&self.capabilities()) } @@ -83,6 +95,11 @@ pub trait SysEntityAttributesExt: SysEntityAttribut fn attribute, E>(&self, attr: A) -> Result> { attr.parse(self) } + + /// Set an attribute on the entity + fn set(&self, attr: A, value: V) -> IoResult<()> { + attr.write_str(self, &value.to_string()) + } } impl > SysEntityAttributesExt for X {} diff --git a/src/hwmon.rs b/src/hwmon.rs index faed7a2..b3c877e 100644 --- a/src/hwmon.rs +++ b/src/hwmon.rs @@ -96,6 +96,8 @@ pub enum HwMonAttributeItem { Min, /// Maximum Max, + /// Readable name for another attribute + Label, } impl HwMonAttributeItem { @@ -104,6 +106,7 @@ impl HwMonAttributeItem { Self::Input => "input", Self::Min => "min", Self::Max => "max", + Self::Label => "label" } } @@ -213,7 +216,7 @@ impl HwMonPath { } /// Get a hwmon attribute (file contents) - pub fn attribute(&self, attr: HwMonAttribute) -> IoResult { + fn attribute(&self, attr: HwMonAttribute) -> IoResult { self.attribute_str(&attr.to_attr_str()) } diff --git a/src/lib.rs b/src/lib.rs index 8384d6f..713d445 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,7 +13,7 @@ pub use basic::BasicEntityPath; pub mod capability; mod entity; -pub use entity::{EntityPath, SysEntity, SysEntityRawExt, SysEntityAttributes}; +pub use entity::{EntityPath, SysEntity, SysEntityRawExt, SysEntityAttributes, SysEntityAttributesExt}; mod errors; pub use errors::{EitherErr2, ValueEnumError};