unitforge 0.5.2

A library for unit and quantity consistent computations in Rust
Documentation
use core::fmt;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum UnitforgeError {
    QuantityConversion(QuantityConversionError),
    QuantityOperation(QuantityOperationError),
    Linalg(LinalgError),
}

pub type UnitforgeResult<T> = Result<T, UnitforgeError>;

impl fmt::Display for UnitforgeError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            UnitforgeError::QuantityConversion(err) => err.fmt(f),
            UnitforgeError::QuantityOperation(err) => err.fmt(f),
            UnitforgeError::Linalg(err) => err.fmt(f),
        }
    }
}

impl From<QuantityConversionError> for UnitforgeError {
    fn from(value: QuantityConversionError) -> Self {
        UnitforgeError::QuantityConversion(value)
    }
}

impl From<QuantityOperationError> for UnitforgeError {
    fn from(value: QuantityOperationError) -> Self {
        UnitforgeError::QuantityOperation(value)
    }
}

impl From<LinalgError> for UnitforgeError {
    fn from(value: LinalgError) -> Self {
        UnitforgeError::Linalg(value)
    }
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum QuantityConversionError {
    InvalidQuantityUnitPair,
    InvalidQuantityExtraction,
    InvalidPythonQuantity,
    InvalidPythonUnit,
    UnknownQuantityKindId { kind_id: u32 },
    UnknownUnitKindId { kind_id: u32 },
    UnknownUnitVariantId { kind_id: u32, variant_id: i32 },
}

pub type QuantityConversionResult<T> = Result<T, QuantityConversionError>;

impl fmt::Display for QuantityConversionError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            QuantityConversionError::InvalidQuantityUnitPair => {
                write!(f, "Cannot use given pair of quantity and unit")
            }
            QuantityConversionError::InvalidQuantityExtraction => {
                write!(f, "Cannot extract requested quantity type")
            }
            QuantityConversionError::InvalidPythonQuantity => {
                write!(f, "Cannot interpret given value as Quantity")
            }
            QuantityConversionError::InvalidPythonUnit => {
                write!(f, "Cannot interpret given value as Unit")
            }
            QuantityConversionError::UnknownQuantityKindId { kind_id } => {
                write!(f, "Unknown quantity kind id: {kind_id}")
            }
            QuantityConversionError::UnknownUnitKindId { kind_id } => {
                write!(f, "Unknown unit kind id: {kind_id}")
            }
            QuantityConversionError::UnknownUnitVariantId {
                kind_id,
                variant_id,
            } => write!(
                f,
                "Unknown unit variant id {variant_id} for unit kind id {kind_id}"
            ),
        }
    }
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum QuantityOperationError {
    AddError,
    SubError,
    MulError,
    DivError,
    PowError,
    SqrtError,
    ComparisonError,
}

pub type QuantityOperationResult<T> = Result<T, QuantityOperationError>;

impl fmt::Display for QuantityOperationError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            QuantityOperationError::AddError => write!(f, "Addition operation failed"),
            QuantityOperationError::SubError => write!(f, "Subtraction operation failed"),
            QuantityOperationError::MulError => write!(f, "Multiplication operation failed"),
            QuantityOperationError::DivError => write!(f, "Division operation failed"),
            QuantityOperationError::PowError => write!(f, "Power operation failed"),
            QuantityOperationError::SqrtError => write!(f, "Sqrt operation failed"),
            QuantityOperationError::ComparisonError => write!(f, "Comparison operation failed"),
        }
    }
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum LinalgShape {
    Vector { len: usize },
    Matrix { rows: usize, cols: usize },
}

impl fmt::Display for LinalgShape {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            LinalgShape::Vector { len } => write!(f, "vector length {len}"),
            LinalgShape::Matrix { rows, cols } => write!(f, "matrix shape {rows}x{cols}"),
        }
    }
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum LinalgError {
    ShapeMismatch {
        expected: LinalgShape,
        actual: LinalgShape,
    },
    ShapeConstructionFailed,
}

pub type LinalgResult<T> = Result<T, LinalgError>;

impl fmt::Display for LinalgError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            LinalgError::ShapeMismatch { expected, actual } => {
                write!(f, "Shape mismatch: expected {expected}, got {actual}")
            }
            LinalgError::ShapeConstructionFailed => write!(f, "Shape construction failed"),
        }
    }
}

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

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

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

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