Skip to main content

aorist_extendr_api/
error.rs

1//! Error handling in Rust called from R.
2
3use crate::{throw_r_error, Robj};
4
5/// Throw an R error if a result is an error.
6#[doc(hidden)]
7pub fn unwrap_or_throw<T>(r: std::result::Result<T, &'static str>) -> T {
8    match r {
9        Err(e) => {
10            throw_r_error(e.to_string());
11            unreachable!("");
12        }
13        Ok(v) => v,
14    }
15}
16
17#[doc(hidden)]
18pub fn unwrap_or_throw_error<T>(r: std::result::Result<T, Error>) -> T {
19    match r {
20        Err(e) => {
21            throw_r_error(e.to_string());
22            unreachable!("");
23        }
24        Ok(v) => v,
25    }
26}
27
28#[derive(Debug, PartialEq)]
29pub enum Error {
30    Panic(Robj),
31    NotFound(Robj),
32    EvalError(Robj),
33    ParseError(Robj),
34    NamesLengthMismatch(Robj),
35
36    ExpectedNull(Robj),
37    ExpectedSymbol(Robj),
38    ExpectedPairlist(Robj),
39    ExpectedFunction(Robj),
40    ExpectedEnvironment(Robj),
41    ExpectedPromise(Robj),
42    ExpectedLanguage(Robj),
43    ExpectedSpecial(Robj),
44    ExpectedBuiltin(Robj),
45    ExpectedCharacter(Robj),
46    ExpectedLogical(Robj),
47    ExpectedInteger(Robj),
48    ExpectedReal(Robj),
49    ExpectedComplex(Robj),
50    ExpectedString(Robj),
51    ExpectedDot(Robj),
52    ExpectedAny(Robj),
53    ExpectedList(Robj),
54    ExpectedExpression(Robj),
55    ExpectedBytecode(Robj),
56    ExpectedExternalPtr(Robj),
57    ExpectedWeakRef(Robj),
58    ExpectedRaw(Robj),
59    ExpectedS4(Robj),
60    ExpectedPrimitive(Robj),
61
62    ExpectedScalar(Robj),
63    ExpectedVector(Robj),
64    ExpectedMatrix(Robj),
65    ExpectedMatrix3D(Robj),
66    ExpectedNumeric(Robj),
67    OutOfRange(Robj),
68    MustNotBeNA(Robj),
69    ExpectedNonZeroLength(Robj),
70    TypeMismatch(Robj),
71    NamespaceNotFound(Robj),
72
73    Other(String),
74}
75
76impl std::fmt::Display for Error {
77    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78        match self {
79            Error::Panic(robj) => write!(f, "Panic detected {:?}.", robj),
80            Error::NotFound(robj) => write!(f, "Not found. {:?}", robj),
81            Error::EvalError(robj) => write!(f, "Evaluation error in {:?}.", robj),
82            Error::ParseError(code) => write!(f, "Parse error in {:?}.", code),
83            Error::NamesLengthMismatch(robj) => {
84                write!(f, "Length of names does not match vector. {:?}", robj)
85            }
86
87            Error::ExpectedNull(robj) => write!(f, "Expected Null got {:?}", robj.rtype()),
88            Error::ExpectedSymbol(robj) => write!(f, "Expected Symbol got {:?}", robj.rtype()),
89            Error::ExpectedPairlist(robj) => write!(f, "Expected Pairlist got {:?}", robj.rtype()),
90            Error::ExpectedFunction(robj) => write!(f, "Expected Function got {:?}", robj.rtype()),
91            Error::ExpectedEnvironment(robj) => {
92                write!(f, "Expected Environment got {:?}", robj.rtype())
93            }
94            Error::ExpectedPromise(robj) => write!(f, "Expected Promise got {:?}", robj.rtype()),
95            Error::ExpectedLanguage(robj) => write!(f, "Expected Language got {:?}", robj.rtype()),
96            Error::ExpectedSpecial(robj) => write!(f, "Expected Special got {:?}", robj.rtype()),
97            Error::ExpectedBuiltin(robj) => write!(f, "Expected Builtin got {:?}", robj.rtype()),
98            Error::ExpectedCharacter(robj) => {
99                write!(f, "Expected Character got {:?}", robj.rtype())
100            }
101            Error::ExpectedLogical(robj) => write!(f, "Expected Logical got {:?}", robj.rtype()),
102            Error::ExpectedInteger(robj) => write!(f, "Expected Integer got {:?}", robj.rtype()),
103            Error::ExpectedReal(robj) => write!(f, "Expected Real got {:?}", robj.rtype()),
104            Error::ExpectedComplex(robj) => write!(f, "Expected Complex got {:?}", robj.rtype()),
105            Error::ExpectedString(robj) => write!(f, "Expected String got {:?}", robj.rtype()),
106            Error::ExpectedDot(robj) => write!(f, "Expected Dot got {:?}", robj.rtype()),
107            Error::ExpectedAny(robj) => write!(f, "Expected Any got {:?}", robj.rtype()),
108            Error::ExpectedList(robj) => write!(f, "Expected List got {:?}", robj.rtype()),
109            Error::ExpectedExpression(robj) => {
110                write!(f, "Expected Expression got {:?}", robj.rtype())
111            }
112            Error::ExpectedBytecode(robj) => write!(f, "Expected Bytecode got {:?}", robj.rtype()),
113            Error::ExpectedExternalPtr(robj) => {
114                write!(f, "Expected ExternalPtr got {:?}", robj.rtype())
115            }
116            Error::ExpectedWeakRef(robj) => write!(f, "Expected WeakRef got {:?}", robj.rtype()),
117            Error::ExpectedRaw(robj) => write!(f, "Expected Raw got {:?}", robj.rtype()),
118            Error::ExpectedS4(robj) => write!(f, "Expected S4 got {:?}", robj.rtype()),
119            Error::ExpectedPrimitive(robj) => {
120                write!(f, "Expected Primitive got {:?}", robj.rtype())
121            }
122
123            Error::ExpectedScalar(robj) => write!(f, "Expected Scalar, got {:?}", robj.rtype()),
124            Error::ExpectedVector(robj) => write!(f, "Expected Vector, got {:?}", robj.rtype()),
125            Error::ExpectedMatrix(robj) => write!(f, "Expected Matrix, got {:?}", robj.rtype()),
126            Error::ExpectedMatrix3D(robj) => write!(f, "Expected Matrix3D, got {:?}", robj.rtype()),
127            Error::ExpectedNumeric(robj) => write!(f, "Expected Numeric, got {:?}", robj.rtype()),
128            Error::OutOfRange(_robj) => write!(f, "Out of range."),
129            Error::MustNotBeNA(_robj) => write!(f, "Must not be NA."),
130            Error::ExpectedNonZeroLength(_robj) => write!(f, "Expected non zero length"),
131            Error::TypeMismatch(_robj) => write!(f, "Type mismatch"),
132
133            Error::NamespaceNotFound(robj) => write!(f, "Namespace {:?} not found", robj),
134            Error::Other(str) => write!(f, "{}", str),
135        }
136    }
137}
138pub type Result<T> = std::result::Result<T, Error>;
139
140// impl std::fmt::Display for Error {
141//     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
142//         write!(f, "{:?}", self)
143//     }
144// }
145
146impl std::error::Error for Error {
147    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
148        None
149    }
150}
151
152impl From<Box<dyn std::error::Error>> for Error {
153    fn from(err: Box<dyn std::error::Error>) -> Error {
154        Error::Other(format!("{}", err))
155    }
156}
157
158impl From<&str> for Error {
159    fn from(err: &str) -> Error {
160        Error::Other(err.to_string())
161    }
162}
163
164impl From<String> for Error {
165    fn from(err: String) -> Error {
166        Error::Other(err)
167    }
168}
169
170// NoneError is unstable.
171//
172// impl From<std::option::NoneError> for Error {
173//     fn from(err: std::option::NoneError) -> Error {
174//         Error::None
175//     }
176// }