use std::path::Path;
use std::convert::AsRef;
use std::io::Result as IoResult;
use crate::EitherErr2;
use crate::SysAttributeExt;
#[cfg(feature = "derive")]
pub trait SysEntity: AsRef<Path> + core::fmt::Debug {
fn to_entity_path(self) -> EntityPath;
fn name(&self) -> IoResult<String>;
fn root(&self) -> Option<crate::SysPath> {
crate::SysPath::from_entity_path(self)
}
}
#[cfg(not(feature = "derive"))]
pub trait SysEntity: AsRef<Path> {
fn to_entity_path(self) -> EntityPath;
fn name(&self) -> IoResult<String>;
fn root(&self) -> Option<crate::SysPath> {
crate::SysPath::from_entity_path(self)
}
}
pub trait SysEntityRawExt: SysEntity {
fn attribute<A: crate::SysAttribute, T: std::str::FromStr<Err=E>, E>(&self, attr: A) -> Result<T, EitherErr2<std::io::Error, E>>;
fn attribute_str<A: AsRef<Path>>(&self, attr: A) -> IoResult<String>;
fn exists<A: crate::SysAttribute>(&self, attr: A) -> bool;
fn exists_str<A: AsRef<Path>>(&self, attr: A) -> bool;
}
impl <X: SysEntity> SysEntityRawExt for X {
fn attribute<A: crate::SysAttribute, T: std::str::FromStr<Err=E>, E>(&self, attr: A) -> Result<T, EitherErr2<std::io::Error, E>> {
attr.parse(self)
}
fn attribute_str<A: AsRef<Path>>(&self, attr: A) -> IoResult<String> {
std::fs::read_to_string(self.as_ref().join(attr))
}
fn exists_str<A: AsRef<Path>>(&self, attr: A) -> bool {
self.as_ref().join(attr).exists()
}
fn exists<A: crate::SysAttribute>(&self, attr: A) -> bool {
attr.exists(self)
}
}
pub trait SysEntityAttributes<A: crate::SysAttribute>: SysEntity {
fn capabilities(&self) -> Vec<A>;
}
pub trait SysEntityAttributesExt<A: crate::SysAttribute>: SysEntityAttributes<A> + Sized {
fn capable<C: crate::capability::Capabilities<A, Self>>(&self, mut capabilities: C) -> bool {
capabilities.satisfies(self)
}
fn attribute<T: std::str::FromStr<Err=E>, E>(&self, attr: A) -> Result<T, EitherErr2<std::io::Error, E>> {
attr.parse(self)
}
fn set<V: std::string::ToString>(&self, attr: A, value: V) -> IoResult<()> {
attr.write_str(self, &value.to_string())
}
fn read_value(&self, attr: &A) -> IoResult<Vec<u8>> {
attr.read_value(self)
}
fn write_value(&self, attr: &A, value: &[u8]) -> IoResult<()> {
attr.write_value(self, value)
}
fn exists(&self, attr: &A) -> bool {
attr.exists(self)
}
}
impl <A: crate::SysAttribute, X: SysEntityAttributes<A>> SysEntityAttributesExt<A> for X {}
#[cfg_attr(feature = "derive", derive(Debug, Clone))]
pub enum EntityPath {
HwMon(crate::HwMonPath),
PowerSupply(crate::PowerSupplyPath),
Generic(crate::BasicEntityPath),
Custom(std::sync::Arc<Box<dyn SysEntity>>),
}
impl EntityPath {
fn inner(&self) -> &'_ dyn SysEntity {
match self {
Self::HwMon(inner) => inner,
Self::PowerSupply(inner) => inner,
Self::Generic(inner) => inner,
Self::Custom(inner) => inner.as_ref().as_ref(),
}
}
}
impl AsRef<Path> for EntityPath {
fn as_ref(&self) -> &Path {
self.inner().as_ref()
}
}
impl SysEntity for EntityPath {
fn to_entity_path(self) -> Self {
self
}
fn name(&self) -> IoResult<String> {
self.inner().name()
}
}