use super::*;
use crate::hwmon::*;
use crate::units::{AngularVelocity, FanDivisor, Raw};
use crate::{Parseable, ParsingResult};
#[cfg(feature = "writable")]
use std::convert::TryFrom;
use std::path::{Path, PathBuf};
pub trait FanSensor: SensorBase {
fn read_target(&self) -> Result<AngularVelocity> {
let raw = self.read_raw(SensorSubFunctionType::Target)?;
AngularVelocity::from_raw(&raw).map_err(Error::from)
}
fn read_div(&self) -> Result<FanDivisor> {
let raw = self.read_raw(SensorSubFunctionType::Div)?;
FanDivisor::from_raw(&raw).map_err(Error::from)
}
#[cfg(feature = "writable")]
fn write_target(&self, target: AngularVelocity) -> Result<()>
where
Self: WritableSensorBase,
{
self.write_raw(SensorSubFunctionType::Target, &target.to_raw())
}
#[cfg(feature = "writable")]
fn write_div(&self, div: FanDivisor) -> Result<()>
where
Self: WritableSensorBase,
{
self.write_raw(SensorSubFunctionType::Div, &div.to_raw())
}
}
impl<S: FanSensor + Faulty> Sensor<AngularVelocity> for S {
fn read_input(&self) -> Result<AngularVelocity> {
if self.read_faulty().unwrap_or(false) {
return Err(Error::FaultySensor);
}
let raw = self.read_raw(SensorSubFunctionType::Input)?;
AngularVelocity::from_raw(&raw).map_err(Error::from)
}
}
impl<S: FanSensor> Min<AngularVelocity> for S {}
impl<S: FanSensor> Max<AngularVelocity> for S {}
#[derive(Debug, Clone)]
pub struct ReadOnlyFan {
hwmon_path: PathBuf,
index: u16,
}
impl SensorBase for ReadOnlyFan {
fn base(&self) -> &'static str {
"fan"
}
fn index(&self) -> u16 {
self.index
}
fn hwmon_path(&self) -> &Path {
self.hwmon_path.as_path()
}
}
impl Parseable for ReadOnlyFan {
type Parent = ReadOnlyHwmon;
fn parse(parent: &Self::Parent, index: u16) -> ParsingResult<Self> {
let fan = Self {
hwmon_path: parent.path().to_path_buf(),
index,
};
inspect_sensor(fan)
}
}
impl FanSensor for ReadOnlyFan {}
impl Faulty for ReadOnlyFan {}
#[cfg(feature = "writable")]
impl From<ReadWriteFan> for ReadOnlyFan {
fn from(write_fan: ReadWriteFan) -> ReadOnlyFan {
ReadOnlyFan {
hwmon_path: write_fan.hwmon_path,
index: write_fan.index,
}
}
}
#[cfg(feature = "writable")]
#[derive(Debug, Clone)]
pub struct ReadWriteFan {
hwmon_path: PathBuf,
index: u16,
}
#[cfg(feature = "writable")]
impl SensorBase for ReadWriteFan {
fn base(&self) -> &'static str {
"fan"
}
fn index(&self) -> u16 {
self.index
}
fn hwmon_path(&self) -> &Path {
self.hwmon_path.as_path()
}
}
#[cfg(feature = "writable")]
impl Parseable for ReadWriteFan {
type Parent = ReadWriteHwmon;
fn parse(parent: &Self::Parent, index: u16) -> ParsingResult<Self> {
let fan = Self {
hwmon_path: parent.path().to_path_buf(),
index,
};
inspect_sensor(fan)
}
}
#[cfg(feature = "writable")]
impl FanSensor for ReadWriteFan {}
#[cfg(feature = "writable")]
impl Faulty for ReadWriteFan {}
#[cfg(feature = "writable")]
impl WritableSensorBase for ReadWriteFan {}
#[cfg(feature = "writable")]
impl TryFrom<ReadOnlyFan> for ReadWriteFan {
type Error = Error;
fn try_from(value: ReadOnlyFan) -> std::result::Result<Self, Self::Error> {
let read_write = ReadWriteFan {
hwmon_path: value.hwmon_path,
index: value.index,
};
if read_write.supported_write_sub_functions().is_empty() {
return Err(Error::InsufficientRights {
path: read_write.hwmon_path.join(format!(
"{}{}",
read_write.base(),
read_write.index(),
)),
});
}
Ok(read_write)
}
}