Skip to main content

cjc_runtime/
error.rs

1use std::fmt;
2
3// ---------------------------------------------------------------------------
4// Error types
5// ---------------------------------------------------------------------------
6
7/// Errors produced by the CJC runtime.
8///
9/// All runtime operations that can fail return `Result<T, RuntimeError>`.
10/// This enum covers the four main failure modes: index violations, shape
11/// incompatibilities, dimension mismatches, and general invalid operations.
12///
13/// [`RuntimeError`] implements [`std::error::Error`] and [`Display`] for
14/// integration with Rust's standard error handling.
15#[derive(Debug, Clone)]
16pub enum RuntimeError {
17    /// An index exceeded the valid range for a buffer or tensor dimension.
18    ///
19    /// `index` is the out-of-bounds index that was provided, and `length`
20    /// is the size of the dimension or buffer that was indexed into.
21    IndexOutOfBounds {
22        /// The invalid index that was provided.
23        index: usize,
24        /// The valid range is `0..length`.
25        length: usize,
26    },
27    /// The total number of elements did not match what the shape requires.
28    ///
29    /// Raised by [`Tensor::from_vec`] when `data.len() != product(shape)`,
30    /// and by [`Tensor::reshape`] when the new shape's element count differs.
31    ShapeMismatch {
32        /// The element count implied by the target shape.
33        expected: usize,
34        /// The actual element count provided.
35        got: usize,
36    },
37    /// The number of dimensions (rank) did not match what was expected.
38    ///
39    /// Raised by operations like [`Tensor::matmul`] (requires 2-D) or
40    /// [`Tensor::get`] (index length must match ndim).
41    DimensionMismatch {
42        /// The required number of dimensions.
43        expected: usize,
44        /// The actual number of dimensions provided.
45        got: usize,
46    },
47    /// A catch-all for operations that are invalid for the given arguments.
48    ///
49    /// The contained `String` provides a human-readable description of
50    /// what went wrong (e.g., "matmul requires 2-D tensors").
51    InvalidOperation(String),
52}
53
54impl fmt::Display for RuntimeError {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        match self {
57            RuntimeError::IndexOutOfBounds { index, length } => {
58                write!(f, "index {index} out of bounds for length {length}")
59            }
60            RuntimeError::ShapeMismatch { expected, got } => {
61                write!(f, "shape mismatch: expected {expected} elements, got {got}")
62            }
63            RuntimeError::DimensionMismatch { expected, got } => {
64                write!(
65                    f,
66                    "dimension mismatch: expected {expected} dimensions, got {got}"
67                )
68            }
69            RuntimeError::InvalidOperation(msg) => {
70                write!(f, "invalid operation: {msg}")
71            }
72        }
73    }
74}
75
76impl std::error::Error for RuntimeError {}
77