libfancontrold 0.4.0

Base library for fancontrold.
Documentation
use crate::{address::Error as AddressError, config::Error as ConfigError, Address};

use std::{
    convert::Infallible,
    error::Error as StdError,
    fmt::{Display, Formatter, Result as FmtResult},
    path::PathBuf,
};

use libmedium::sensors::Error as SensorError;
use libmedium::ParsingError;

/// The different error types Error can be.
#[derive(Debug)]
pub enum Error {
    Parsing { source: ParsingError },
    Config { source: ConfigError },
    SensorNotFound { source: AddressError },
    PwmNotWritable { address: Address },
    PwmEnable { source: SensorError },
    VirtualTempNotFound { path: PathBuf, source: SensorError },
}

impl Error {
    pub(crate) fn sensor_not_found(source: AddressError) -> Self {
        Error::SensorNotFound { source }
    }

    pub(crate) fn pwm_not_writable(address: Address) -> Self {
        Error::PwmNotWritable { address }
    }

    pub(crate) fn pwm_enable(source: SensorError) -> Self {
        Error::PwmEnable { source }
    }

    pub(crate) fn virtual_temp_not_found(path: impl Into<PathBuf>, source: SensorError) -> Self {
        Error::VirtualTempNotFound {
            path: path.into(),
            source,
        }
    }
}

impl Display for Error {
    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
        match self {
            Error::Parsing { source } => write!(f, "Parsing error: {}", source),
            Error::Config { source } => write!(f, "Config produced an error: {}", source),
            Error::SensorNotFound { source } => write!(f, "Sensor could not be found: {}", source),
            Error::PwmNotWritable { address } => {
                write!(f, "Pwm sensor at {} is not writable.", address)
            }
            Error::PwmEnable { source } => write!(f, "Error setting pwm_enable value: {}.", source),
            Error::VirtualTempNotFound { path, source } => {
                write!(
                    f,
                    "Error reading virtual temp sensor at {}: {}",
                    path.display(),
                    source
                )
            }
        }
    }
}

impl StdError for Error {
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        match self {
            Error::Parsing { source } => Some(source),
            Error::Config { source, .. } => Some(source),
            Error::SensorNotFound { source } => Some(source),
            Error::PwmNotWritable { .. } => None,
            Error::PwmEnable { source } => Some(source),
            Error::VirtualTempNotFound { source, .. } => Some(source),
        }
    }
}

impl From<ConfigError> for Error {
    fn from(source: ConfigError) -> Self {
        Error::Config { source }
    }
}

impl From<ParsingError> for Error {
    fn from(source: ParsingError) -> Self {
        Error::Parsing { source }
    }
}

impl From<AddressError> for Error {
    fn from(source: AddressError) -> Self {
        Error::SensorNotFound { source }
    }
}

impl From<Infallible> for Error {
    fn from(_: Infallible) -> Self {
        unreachable!()
    }
}