ndarray/
error.rs

1// Copyright 2014-2016 bluss and ndarray developers.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8use super::Dimension;
9#[cfg(feature = "std")]
10use std::error::Error;
11use std::fmt;
12
13/// An error related to array shape or layout.
14#[derive(Clone)]
15pub struct ShapeError {
16    // we want to be able to change this representation later
17    repr: ErrorKind,
18}
19
20impl ShapeError {
21    /// Return the `ErrorKind` of this error.
22    #[inline]
23    pub fn kind(&self) -> ErrorKind {
24        self.repr
25    }
26
27    /// Create a new `ShapeError`
28    pub fn from_kind(error: ErrorKind) -> Self {
29        from_kind(error)
30    }
31}
32
33/// Error code for an error related to array shape or layout.
34///
35/// This enumeration is not exhaustive. The representation of the enum
36/// is not guaranteed.
37#[non_exhaustive]
38#[derive(Copy, Clone, Debug)]
39pub enum ErrorKind {
40    /// incompatible shape
41    IncompatibleShape = 1,
42    /// incompatible memory layout
43    IncompatibleLayout,
44    /// the shape does not fit inside type limits
45    RangeLimited,
46    /// out of bounds indexing
47    OutOfBounds,
48    /// aliasing array elements
49    Unsupported,
50    /// overflow when computing offset, length, etc.
51    Overflow,
52}
53
54#[inline(always)]
55pub fn from_kind(k: ErrorKind) -> ShapeError {
56    ShapeError { repr: k }
57}
58
59impl PartialEq for ErrorKind {
60    #[inline(always)]
61    fn eq(&self, rhs: &Self) -> bool {
62        *self as u8 == *rhs as u8
63    }
64}
65
66impl PartialEq for ShapeError {
67    #[inline(always)]
68    fn eq(&self, rhs: &Self) -> bool {
69        self.repr == rhs.repr
70    }
71}
72
73#[cfg(feature = "std")]
74impl Error for ShapeError {}
75
76impl fmt::Display for ShapeError {
77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78        let description = match self.kind() {
79            ErrorKind::IncompatibleShape => "incompatible shapes",
80            ErrorKind::IncompatibleLayout => "incompatible memory layout",
81            ErrorKind::RangeLimited => "the shape does not fit in type limits",
82            ErrorKind::OutOfBounds => "out of bounds indexing",
83            ErrorKind::Unsupported => "unsupported operation",
84            ErrorKind::Overflow => "arithmetic overflow",
85        };
86        write!(f, "ShapeError/{:?}: {}", self.kind(), description)
87    }
88}
89
90impl fmt::Debug for ShapeError {
91    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92        write!(f, "{}", self)
93    }
94}
95
96pub fn incompatible_shapes<D, E>(_a: &D, _b: &E) -> ShapeError
97where
98    D: Dimension,
99    E: Dimension,
100{
101    from_kind(ErrorKind::IncompatibleShape)
102}