tensors-rs 0.1.2

Compact NumPy-like dense tensor primitives for safe numerical Rust.
Documentation
//! Error types used by checked array and linear algebra operations.

use core::fmt;

/// Crate-wide result type.
pub type Result<T> = core::result::Result<T, Error>;

/// Checked operation failures.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {
    /// A shape does not match the number of elements or another operand.
    ShapeMismatch {
        /// Expected shape or length.
        expected: Vec<usize>,
        /// Actual shape or length.
        actual: Vec<usize>,
    },
    /// A view was required to be contiguous but is strided.
    NonContiguous,
    /// A stride or offset points outside the backing allocation.
    InvalidStride,
    /// Requested rank exceeds the matrix dimensions.
    RankTooLarge {
        /// Requested rank.
        requested: usize,
        /// Maximum valid rank.
        max: usize,
    },
    /// Dimension arithmetic overflowed `usize`.
    DimensionTooLarge,
    /// Allocation failed or would exceed addressable dimensions.
    AllocationFailed,
    /// An iterative method did not converge.
    NotConverged,
    /// Numerical breakdown, such as a near-zero norm during factorization.
    NumericalFailure(&'static str),
    /// An axis index is out of bounds.
    AxisOutOfBounds {
        /// Requested axis.
        axis: usize,
        /// Number of axes.
        ndim: usize,
    },
    /// An index is out of bounds.
    IndexOutOfBounds,
}

impl Error {
    pub(crate) fn shape(expected: impl Into<Vec<usize>>, actual: impl Into<Vec<usize>>) -> Self {
        Self::ShapeMismatch {
            expected: expected.into(),
            actual: actual.into(),
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::ShapeMismatch { expected, actual } => {
                write!(f, "shape mismatch: expected {expected:?}, got {actual:?}")
            }
            Self::NonContiguous => write!(f, "array view is not contiguous"),
            Self::InvalidStride => write!(f, "invalid stride or offset"),
            Self::RankTooLarge { requested, max } => {
                write!(f, "rank {requested} exceeds maximum valid rank {max}")
            }
            Self::DimensionTooLarge => write!(f, "dimension is too large"),
            Self::AllocationFailed => write!(f, "allocation failed"),
            Self::NotConverged => write!(f, "algorithm did not converge"),
            Self::NumericalFailure(msg) => write!(f, "numerical failure: {msg}"),
            Self::AxisOutOfBounds { axis, ndim } => {
                write!(f, "axis {axis} out of bounds for {ndim} dimensions")
            }
            Self::IndexOutOfBounds => write!(f, "index out of bounds"),
        }
    }
}

impl std::error::Error for Error {}