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 ExpectedNumeric(Robj),
69 ExpectedAltrep(Robj),
70 ExpectedDataframe(Robj),
71
72 OutOfRange(Robj),
73 MustNotBeNA(Robj),
74 ExpectedWholeNumber(Robj, ConversionError),
75 ExpectedNonZeroLength(Robj),
76 OutOfLimits(Robj),
77 TypeMismatch(Robj),
78 NamespaceNotFound(Robj),
79 NoGraphicsDevices(Robj),
80
81 ExpectedExternalPtrType(Robj, String),
82 ExpectedExternalNonNullPtr(Robj),
83 ExpectedExternalPtrReference,
84 Other(String),
85
86 #[cfg(feature = "ndarray")]
87 NDArrayShapeError(ndarray::ShapeError),
88
89 #[cfg(feature = "either")]
90 EitherError(Box<Error>, Box<Error>),
91}
92
93impl std::fmt::Display for Error {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 match self {
96 Error::Panic(robj) => write!(f, "Panic detected {:?}.", robj),
97 Error::NotFound(robj) => write!(f, "Not found. {:?}", robj),
98 Error::EvalError(robj) => write!(f, "Evaluation error in {:?}.", robj),
99 Error::ParseError(code) => write!(f, "Parse error in {:?}.", code),
100 Error::NamesLengthMismatch(robj) => {
101 write!(f, "Length of names does not match vector. {:?}", robj)
102 }
103
104 Error::ExpectedNull(robj) => write!(f, "Expected Null got {:?}", robj.rtype()),
105 Error::ExpectedSymbol(robj) => write!(f, "Expected Symbol got {:?}", robj.rtype()),
106 Error::ExpectedPairlist(robj) => write!(f, "Expected Pairlist got {:?}", robj.rtype()),
107 Error::ExpectedFunction(robj) => write!(f, "Expected Function got {:?}", robj.rtype()),
108 Error::ExpectedEnvironment(robj) => {
109 write!(f, "Expected Environment got {:?}", robj.rtype())
110 }
111 Error::ExpectedPromise(robj) => write!(f, "Expected Promise got {:?}", robj.rtype()),
112 Error::ExpectedLanguage(robj) => write!(f, "Expected Language got {:?}", robj.rtype()),
113 Error::ExpectedSpecial(robj) => write!(f, "Expected Special got {:?}", robj.rtype()),
114 Error::ExpectedBuiltin(robj) => write!(f, "Expected Builtin got {:?}", robj.rtype()),
115 Error::ExpectedRstr(robj) => {
116 write!(f, "Expected Rstr got {:?}", robj.rtype())
117 }
118 Error::ExpectedLogical(robj) => write!(f, "Expected Logicals got {:?}", robj.rtype()),
119 Error::ExpectedInteger(robj) => write!(f, "Expected Integers got {:?}", robj.rtype()),
120 Error::ExpectedReal(robj) => write!(f, "Expected Doubles got {:?}", robj.rtype()),
121 Error::ExpectedComplex(robj) => write!(f, "Expected Complexes got {:?}", robj.rtype()),
122 Error::ExpectedString(robj) => write!(f, "Expected Strings got {:?}", robj.rtype()),
123 Error::ExpectedDot(robj) => write!(f, "Expected Dot got {:?}", robj.rtype()),
124 Error::ExpectedAny(robj) => write!(f, "Expected Any got {:?}", robj.rtype()),
125 Error::ExpectedList(robj) => write!(f, "Expected List got {:?}", robj.rtype()),
126 Error::ExpectedExpression(robj) => {
127 write!(f, "Expected Expression got {:?}", robj.rtype())
128 }
129 Error::ExpectedBytecode(robj) => write!(f, "Expected Bytecode got {:?}", robj.rtype()),
130 Error::ExpectedExternalPtr(robj) => {
131 write!(f, "Expected ExternalPtr got {:?}", robj.rtype())
132 }
133 Error::ExpectedWeakRef(robj) => write!(f, "Expected WeakRef got {:?}", robj.rtype()),
134 Error::ExpectedRaw(robj) => write!(f, "Expected Raw got {:?}", robj.rtype()),
135 Error::ExpectedS4(robj) => write!(f, "Expected S4 got {:?}", robj.rtype()),
136 Error::ExpectedPrimitive(robj) => {
137 write!(f, "Expected Primitive got {:?}", robj.rtype())
138 }
139
140 Error::ExpectedScalar(robj) => write!(f, "Expected Scalar, got {:?}", robj.rtype()),
141 Error::ExpectedVector(robj) => write!(f, "Expected Vector, got {:?}", robj.rtype()),
142 Error::ExpectedMatrix(robj) => write!(f, "Expected Matrix, got {:?}", robj.rtype()),
143 Error::ExpectedMatrix3D(robj) => write!(f, "Expected Matrix3D, got {:?}", robj.rtype()),
144 Error::ExpectedNumeric(robj) => write!(f, "Expected Numeric, got {:?}", robj.rtype()),
145 Error::ExpectedAltrep(robj) => write!(f, "Expected Altrep, got {:?}", robj.rtype()),
146 Error::ExpectedDataframe(robj) => {
147 write!(f, "Expected Dataframe, got {:?}", robj.rtype())
148 }
149
150 Error::OutOfRange(_robj) => write!(f, "Out of range."),
151 Error::MustNotBeNA(_robj) => write!(f, "Must not be NA."),
152 Error::ExpectedNonZeroLength(_robj) => write!(f, "Expected non zero length"),
153 Error::OutOfLimits(robj) => write!(f, "The value is too big: {:?}", robj),
154 Error::TypeMismatch(_robj) => write!(f, "Type mismatch"),
155
156 Error::NamespaceNotFound(robj) => write!(f, "Namespace {:?} not found", robj),
157 Error::ExpectedExternalPtrType(_robj, type_name) => {
158 write!(f, "Incorrect external pointer type {}", type_name)
159 }
160 Error::ExpectedExternalNonNullPtr(robj) => {
161 write!(
162 f,
163 "expected non-null pointer in externalptr, instead {:?}",
164 robj
165 )
166 }
167 Error::ExpectedExternalPtrReference => {
168 write!(f, "It is only possible to return a reference to self.")
169 }
170 Error::NoGraphicsDevices(_robj) => write!(f, "No graphics devices active."),
171 Error::Other(str) => write!(f, "{}", str),
172
173 Error::ExpectedWholeNumber(robj, conversion_error) => {
174 write!(
175 f,
176 "Failed to convert a float to a whole number: {}. Actual value received: {:?}",
177 conversion_error, robj
178 )
179 }
180
181 #[cfg(feature = "ndarray")]
182 Error::NDArrayShapeError(shape_error) => {
183 write!(f, "NDArray failed with error: {}.", shape_error)
184 }
185
186 #[cfg(feature = "either")]
187 Error::EitherError(left_err, right_err) => {
188 write!(
189 f,
190 "Both cases of Either errored. Left: '{}'; Right: '{}'.",
191 left_err, right_err
192 )
193 }
194 }
195 }
196}
197pub type Result<T> = std::result::Result<T, Error>;
198
199impl std::error::Error for Error {
206 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
207 None
208 }
209}
210
211impl From<Box<dyn std::error::Error>> for Error {
212 fn from(err: Box<dyn std::error::Error>) -> Error {
213 Error::Other(format!("{}", err))
214 }
215}
216
217impl From<&str> for Error {
218 fn from(err: &str) -> Error {
219 Error::Other(err.to_string())
220 }
221}
222
223impl From<String> for Error {
224 fn from(err: String) -> Error {
225 Error::Other(err)
226 }
227}
228
229impl From<Infallible> for Error {
238 fn from(_: Infallible) -> Self {
239 Error::Other("".to_string())
240 }
241}