libcpuname 0.1.3

Identify CPU vendors, chips, and cores across multiple architectures
Documentation
use super::Implementer;

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
/// Error type indicating a failure to convert between integer-backed types.
pub struct TryFromIntError;

#[cfg(feature = "std")]
impl std::error::Error for TryFromIntError {}

impl core::fmt::Display for TryFromIntError {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "out of range integral type conversion attempted")
    }
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
/// Error type indicating a failure to find a matching CPU core name.
pub enum CoreNameError {
    /// The provided part exceeds the maximum possible value of `0xFFF`.
    InvalidPart(u16),
    /// The provided variant exceeds the maximum possible value of `0xF`.
    InvalidVariant(u8),
    /// The provided implementer has no known core names.
    NoKnownNamesForImplementer(Implementer),
    /// The provided implementer is known, but the provided part has no known core names.
    NoKnownNamesForPart(u16),
}

#[cfg(feature = "std")]
impl std::error::Error for CoreNameError {}

impl core::fmt::Display for CoreNameError {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::InvalidPart(part) => write!(
                f,
                "provided part {part:X} is greater than the maximum of 0xFFF"
            ),
            Self::InvalidVariant(variant) => write!(
                f,
                "provided variant {variant:X} is greater than the maximum of 0xF"
            ),
            Self::NoKnownNamesForImplementer(implementer) => write!(
                f,
                "provided implementer {implementer} has no known core names"
            ),
            Self::NoKnownNamesForPart(part) => {
                write!(f, "provided part {part:X} has no known core names")
            }
        }
    }
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
/// Composite error type representing all possible errors in this module.
pub enum Error {
    /// Wrapper for [`TryFromIntError`].
    TryFromInt(TryFromIntError),
    /// Wrapper for [`CoreNameError`].
    CoreName(CoreNameError),
}

#[cfg(feature = "std")]
impl std::error::Error for Error {}

impl core::fmt::Display for Error {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::TryFromInt(e) => write!(f, "{e}"),
            Self::CoreName(e) => write!(f, "{e}"),
        }
    }
}

impl From<TryFromIntError> for Error {
    fn from(value: TryFromIntError) -> Self {
        Self::TryFromInt(value)
    }
}

impl From<CoreNameError> for Error {
    fn from(err: CoreNameError) -> Self {
        Self::CoreName(err)
    }
}

#[cfg(test)]
mod tests {
    use super::super::*;
    use super::*;

    #[test]
    fn error_conversion() {
        assert_eq!(
            Error::from(TryFromIntError),
            Error::TryFromInt(TryFromIntError)
        );
        assert_eq!(
            Error::from(CoreNameError::InvalidPart(u16::MAX)),
            Error::CoreName(CoreNameError::InvalidPart(u16::MAX))
        );
    }

    #[test]
    fn display() {
        let errors: &[Error] = &[
            TryFromIntError.into(),
            CoreNameError::InvalidPart(u16::MAX).into(),
            CoreNameError::InvalidVariant(u8::MAX).into(),
            CoreNameError::NoKnownNamesForImplementer(Implementer::Arm).into(),
            CoreNameError::NoKnownNamesForPart(u16::MAX).into(),
        ];

        assert!(errors.iter().all(|it| !it.to_string().is_empty()));
    }
}