1use std::convert::Infallible;
4
5use crate::conversions::try_into_int::ConversionError;
6use crate::robj::Types;
7use crate::{throw_r_error, Robj};
8
9#[doc(hidden)]
11pub fn unwrap_or_throw<T>(r: std::result::Result<T, &'static str>) -> T {
12 match r {
13 Err(e) => {
14 throw_r_error(e);
15 }
16 Ok(v) => v,
17 }
18}
19
20#[doc(hidden)]
21pub fn unwrap_or_throw_error<T>(r: std::result::Result<T, Error>) -> T {
22 match r {
23 Err(e) => {
24 throw_r_error(e.to_string());
25 }
26 Ok(v) => v,
27 }
28}
29
30#[derive(Debug, PartialEq)]
31pub enum Error {
32 Panic(Robj),
33 NotFound(Robj),
34 EvalError(Robj),
35 ParseError(Robj),
36 NamesLengthMismatch(Robj),
37
38 ExpectedNull(Robj),
39 ExpectedSymbol(Robj),
40 ExpectedPairlist(Robj),
41 ExpectedFunction(Robj),
42 ExpectedEnvironment(Robj),
43 ExpectedPromise(Robj),
44 ExpectedLanguage(Robj),
45 ExpectedSpecial(Robj),
46 ExpectedBuiltin(Robj),
47 ExpectedRstr(Robj),
48 ExpectedLogical(Robj),
49 ExpectedInteger(Robj),
50 ExpectedReal(Robj),
51 ExpectedComplex(Robj),
52 ExpectedString(Robj),
53 ExpectedDot(Robj),
54 ExpectedAny(Robj),
55 ExpectedList(Robj),
56 ExpectedExpression(Robj),
57 ExpectedBytecode(Robj),
58 ExpectedExternalPtr(Robj),
59 ExpectedWeakRef(Robj),
60 ExpectedRaw(Robj),
61 ExpectedS4(Robj),
62 ExpectedPrimitive(Robj),
63
64 ExpectedScalar(Robj),
65 ExpectedVector(Robj),
66 ExpectedMatrix(Robj),
67 ExpectedMatrix3D(Robj),
68 ExpectedMatrix4D(Robj),
69 ExpectedMatrix5D(Robj),
70 ExpectedNumeric(Robj),
71 ExpectedAltrep(Robj),
72 ExpectedDataframe(Robj),
73
74 OutOfRange(Robj),
75 MustNotBeNA(Robj),
76 ExpectedWholeNumber(Robj, ConversionError),
77 ExpectedNonZeroLength(Robj),
78 ExpectedLength(usize),
79 OutOfLimits(Robj),
80 TypeMismatch(Robj),
81 NamespaceNotFound(Robj),
82 NoGraphicsDevices(Robj),
83
84 ExpectedExternalPtrType(Robj, String),
85 ExpectedExternalNonNullPtr(Robj),
86 ExpectedExternalPtrReference,
87 Other(String),
88
89 #[cfg(feature = "ndarray")]
90 NDArrayShapeError(ndarray::ShapeError),
91
92 #[cfg(feature = "either")]
93 EitherError(Box<Error>, Box<Error>),
94 TryFromSliceError(String),
96}
97
98impl std::fmt::Display for Error {
99 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100 match self {
101 Error::Panic(robj) => write!(f, "Panic detected {:?}.", robj),
102 Error::NotFound(robj) => write!(f, "Not found. {:?}", robj),
103 Error::EvalError(robj) => write!(f, "Evaluation error in {:?}.", robj),
104 Error::ParseError(code) => write!(f, "Parse error in {:?}.", code),
105 Error::NamesLengthMismatch(robj) => {
106 write!(f, "Length of names does not match vector. {:?}", robj)
107 }
108
109 Error::ExpectedNull(robj) => write!(f, "Expected Null got {:?}", robj.rtype()),
110 Error::ExpectedSymbol(robj) => write!(f, "Expected Symbol got {:?}", robj.rtype()),
111 Error::ExpectedPairlist(robj) => write!(f, "Expected Pairlist got {:?}", robj.rtype()),
112 Error::ExpectedFunction(robj) => write!(f, "Expected Function got {:?}", robj.rtype()),
113 Error::ExpectedEnvironment(robj) => {
114 write!(f, "Expected Environment got {:?}", robj.rtype())
115 }
116 Error::ExpectedPromise(robj) => write!(f, "Expected Promise got {:?}", robj.rtype()),
117 Error::ExpectedLanguage(robj) => write!(f, "Expected Language got {:?}", robj.rtype()),
118 Error::ExpectedSpecial(robj) => write!(f, "Expected Special got {:?}", robj.rtype()),
119 Error::ExpectedBuiltin(robj) => write!(f, "Expected Builtin got {:?}", robj.rtype()),
120 Error::ExpectedRstr(robj) => {
121 write!(f, "Expected Rstr got {:?}", robj.rtype())
122 }
123 Error::ExpectedLogical(robj) => write!(f, "Expected Logicals got {:?}", robj.rtype()),
124 Error::ExpectedInteger(robj) => write!(f, "Expected Integers got {:?}", robj.rtype()),
125 Error::ExpectedReal(robj) => write!(f, "Expected Doubles got {:?}", robj.rtype()),
126 Error::ExpectedComplex(robj) => write!(f, "Expected Complexes got {:?}", robj.rtype()),
127 Error::ExpectedString(robj) => write!(f, "Expected Strings got {:?}", robj.rtype()),
128 Error::ExpectedDot(robj) => write!(f, "Expected Dot got {:?}", robj.rtype()),
129 Error::ExpectedAny(robj) => write!(f, "Expected Any got {:?}", robj.rtype()),
130 Error::ExpectedList(robj) => write!(f, "Expected List got {:?}", robj.rtype()),
131 Error::ExpectedExpression(robj) => {
132 write!(f, "Expected Expression got {:?}", robj.rtype())
133 }
134 Error::ExpectedBytecode(robj) => write!(f, "Expected Bytecode got {:?}", robj.rtype()),
135 Error::ExpectedExternalPtr(robj) => {
136 write!(f, "Expected ExternalPtr got {:?}", robj.rtype())
137 }
138 Error::ExpectedWeakRef(robj) => write!(f, "Expected WeakRef got {:?}", robj.rtype()),
139 Error::ExpectedRaw(robj) => write!(f, "Expected Raw got {:?}", robj.rtype()),
140 Error::ExpectedS4(robj) => write!(f, "Expected S4 got {:?}", robj.rtype()),
141 Error::ExpectedPrimitive(robj) => {
142 write!(f, "Expected Primitive got {:?}", robj.rtype())
143 }
144
145 Error::ExpectedScalar(robj) => write!(f, "Expected Scalar, got {:?}", robj.rtype()),
146 Error::ExpectedVector(robj) => write!(f, "Expected Vector, got {:?}", robj.rtype()),
147 Error::ExpectedMatrix(robj) => write!(f, "Expected Matrix, got {:?}", robj.rtype()),
148 Error::ExpectedMatrix3D(robj) => write!(f, "Expected Matrix3D, got {:?}", robj.rtype()),
149 Error::ExpectedMatrix4D(robj) => write!(f, "Expected Matrix4D, got {:?}", robj.rtype()),
150 Error::ExpectedMatrix5D(robj) => write!(f, "Expected Matrix5D, got {:?}", robj.rtype()),
151 Error::ExpectedNumeric(robj) => write!(f, "Expected Numeric, got {:?}", robj.rtype()),
152 Error::ExpectedAltrep(robj) => write!(f, "Expected Altrep, got {:?}", robj.rtype()),
153 Error::ExpectedDataframe(robj) => {
154 write!(f, "Expected Dataframe, got {:?}", robj.rtype())
155 }
156
157 Error::OutOfRange(_robj) => write!(f, "Out of range."),
158 Error::MustNotBeNA(_robj) => write!(f, "Must not be NA."),
159 Error::ExpectedNonZeroLength(_robj) => write!(f, "Expected non zero length"),
160 Error::ExpectedLength(len) => write!(f, "Expected length: {len}"),
161 Error::OutOfLimits(robj) => write!(f, "The value is too big: {:?}", robj),
162 Error::TypeMismatch(_robj) => write!(f, "Type mismatch"),
163
164 Error::NamespaceNotFound(robj) => write!(f, "Namespace {:?} not found", robj),
165 Error::ExpectedExternalPtrType(_robj, type_name) => {
166 write!(f, "Incorrect external pointer type {}", type_name)
167 }
168 Error::ExpectedExternalNonNullPtr(robj) => {
169 write!(
170 f,
171 "expected non-null pointer in externalptr, instead {:?}",
172 robj
173 )
174 }
175 Error::ExpectedExternalPtrReference => {
176 write!(f, "It is only possible to return a reference to self.")
177 }
178 Error::NoGraphicsDevices(_robj) => write!(f, "No graphics devices active."),
179 Error::TryFromSliceError(std_error) => write!(f, "Rust error: {}", std_error),
181 Error::Other(str) => write!(f, "{}", str),
182
183 Error::ExpectedWholeNumber(robj, conversion_error) => {
184 write!(
185 f,
186 "Failed to convert a float to a whole number: {}. Actual value received: {:?}",
187 conversion_error, robj
188 )
189 }
190
191 #[cfg(feature = "ndarray")]
192 Error::NDArrayShapeError(shape_error) => {
193 write!(f, "NDArray failed with error: {}.", shape_error)
194 }
195
196 #[cfg(feature = "either")]
197 Error::EitherError(left_err, right_err) => {
198 write!(
199 f,
200 "Both cases of Either errored. Left: '{}'; Right: '{}'.",
201 left_err, right_err
202 )
203 }
204 }
205 }
206}
207pub type Result<T> = std::result::Result<T, Error>;
208
209impl std::error::Error for Error {
216 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
217 None
218 }
219}
220
221impl From<Box<dyn std::error::Error>> for Error {
222 fn from(err: Box<dyn std::error::Error>) -> Error {
223 Error::Other(format!("{}", err))
224 }
225}
226
227impl From<&str> for Error {
228 fn from(err: &str) -> Error {
229 Error::Other(err.to_string())
230 }
231}
232
233impl From<String> for Error {
234 fn from(err: String) -> Error {
235 Error::Other(err)
236 }
237}
238
239impl From<Infallible> for Error {
248 fn from(_: Infallible) -> Self {
249 Error::Other("".to_string())
250 }
251}