Skip to main content

fil_ocl_core/
error.rs

1//! Standard error type for ocl.
2//!
3
4use std::fmt;
5use failure::{Context, Fail, Backtrace};
6use crate::util::UtilError;
7use crate::functions::{ApiError, VersionLowError, ProgramBuildError, ApiWrapperError};
8use crate::{Status, EmptyInfoResultError};
9
10
11/// Ocl error result type.
12pub type Result<T> = ::std::result::Result<T, Error>;
13
14
15/// An enum one of several error types.
16#[derive(Debug, Fail)]
17pub enum ErrorKind {
18    // String: An arbitrary error:
19    //
20    // TODO: Remove this eventually. We need to replace every usage
21    // (conversion from String/str) with a dedicated error type/variant for
22    // each. In the meanwhile, refrain from creating new instances of this by
23    // converting strings to `Error`!
24    #[fail(display = "{}", _0)]
25    String(String),
26    // FfiNul: Ffi string conversion error:
27    #[fail(display = "{}", _0)]
28    FfiNul(#[cause] ::std::ffi::NulError),
29    // Io: std::io error:
30    #[fail(display = "{}", _0)]
31    Io(#[cause] ::std::io::Error),
32    // FromUtf8: String conversion error:
33    #[fail(display = "{}", _0)]
34    FromUtf8(#[cause] ::std::string::FromUtf8Error),
35    // IntoString: Ffi string conversion error:
36    #[fail(display = "{}", _0)]
37    IntoString(#[cause] ::std::ffi::IntoStringError),
38    // EmptyInfoResult:
39    #[fail(display = "{}", _0)]
40    EmptyInfoResult(EmptyInfoResultError),
41    // Util:
42    #[fail(display = "{}", _0)]
43    Util(UtilError),
44    // Api:
45    #[fail(display = "{}", _0)]
46    Api(ApiError),
47    // VersionLow:
48    #[fail(display = "{}", _0)]
49    VersionLow(VersionLowError),
50    // ProgramBuild:
51    #[fail(display = "{}", _0)]
52    ProgramBuild(ProgramBuildError),
53    // ApiWrapper:
54    #[fail(display = "{}", _0)]
55    ApiWrapper(ApiWrapperError),
56}
57
58
59/// An Error.
60pub struct Error {
61    inner: Context<ErrorKind>,
62}
63
64impl Error {
65    /// Returns the error status code for `Status` variants.
66    pub fn api_status(&self) -> Option<Status> {
67        match *self.kind() {
68            ErrorKind::Api(ref err) => Some(err.status()),
69            _ => None,
70        }
71    }
72
73    /// Returns the error variant and contents.
74    pub fn kind(&self) -> &ErrorKind {
75        self.inner.get_context()
76    }
77
78    /// Returns the immediate cause of this error (e.g. the next error in the
79    /// chain).
80    pub fn cause(&self) -> Option<&dyn Fail> {
81        self.inner.cause()
82    }
83}
84
85impl fmt::Debug for Error {
86    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87        fmt::Display::fmt(&self.inner, f)
88    }
89}
90
91impl fmt::Display for Error {
92    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
93        fmt::Display::fmt(&self.inner, f)
94    }
95}
96
97impl Fail for Error {
98    fn cause(&self) -> Option<&dyn Fail> {
99        self.inner.cause()
100    }
101
102    fn backtrace(&self) -> Option<&Backtrace> {
103        self.inner.backtrace()
104    }
105}
106
107impl From<ErrorKind> for Error {
108    fn from(kind: ErrorKind) -> Error {
109        Error { inner: Context::new(kind) }
110    }
111}
112
113impl From<Context<ErrorKind>> for Error {
114    fn from(inner: Context<ErrorKind>) -> Error {
115        Error { inner }
116    }
117}
118
119impl From<EmptyInfoResultError> for Error {
120    fn from(err: EmptyInfoResultError) -> Self {
121        Error { inner: Context::new(ErrorKind::EmptyInfoResult(err)) }
122    }
123}
124
125// TODO: Remove eventually
126impl<'a> From<&'a str> for Error {
127    fn from(desc: &'a str) -> Self {
128        Error { inner: Context::new(ErrorKind::String(String::from(desc))) }
129    }
130}
131
132// TODO: Remove eventually
133impl From<String> for Error {
134    fn from(desc: String) -> Self {
135        Error { inner: Context::new(ErrorKind::String(desc)) }
136    }
137}
138
139impl From<::std::ffi::NulError> for Error {
140    fn from(err: ::std::ffi::NulError) -> Self {
141        Error { inner: Context::new(ErrorKind::FfiNul(err)) }
142    }
143}
144
145impl From<::std::io::Error> for Error {
146    fn from(err: ::std::io::Error) -> Self {
147        Error { inner: Context::new(ErrorKind::Io(err)) }
148    }
149}
150
151impl From<::std::string::FromUtf8Error> for Error {
152    fn from(err: ::std::string::FromUtf8Error) -> Self {
153        Error { inner: Context::new(ErrorKind::FromUtf8(err)) }
154    }
155}
156
157impl From<::std::ffi::IntoStringError> for Error {
158    fn from(err: ::std::ffi::IntoStringError) -> Self {
159        Error { inner: Context::new(ErrorKind::IntoString(err)) }
160    }
161}
162
163impl From<UtilError> for Error {
164    fn from(err: UtilError) -> Self {
165        Error { inner: Context::new(ErrorKind::Util(err)) }
166    }
167}
168
169impl From<ApiError> for Error {
170    fn from(err: ApiError) -> Self {
171        Error { inner: Context::new(ErrorKind::Api(err)) }
172    }
173}
174
175impl From<VersionLowError> for Error {
176    fn from(err: VersionLowError) -> Self {
177        Error { inner: Context::new(ErrorKind::VersionLow(err)) }
178    }
179}
180
181impl From<ProgramBuildError> for Error {
182    fn from(err: ProgramBuildError) -> Self {
183        Error { inner: Context::new(ErrorKind::ProgramBuild(err)) }
184    }
185}
186
187impl From<ApiWrapperError> for Error {
188    fn from(err: ApiWrapperError) -> Self {
189        Error { inner: Context::new(ErrorKind::ApiWrapper(err)) }
190    }
191}