1 use libc::{c_int};
2 use std::{self, fmt, result};
3 
4 use gdal_sys::{CPLErr, OGRErr, OGRFieldType};
5 use failure::{Context, Fail, Backtrace};
6 
7 pub type Result<T> = result::Result<T, Error>;
8 
9 #[derive(Debug)]
10 pub struct Error {
11     inner: Context<ErrorKind>,
12 }
13 
14 #[derive(Clone, PartialEq, Debug, Fail)]
15 pub enum ErrorKind {
16 
17     #[fail(display = "FfiNulError")]
18     FfiNulError(#[cause] std::ffi::NulError),
19     #[fail(display = "StrUtf8Error")]
20     StrUtf8Error(#[cause] std::str::Utf8Error),
21     #[cfg(feature = "ndarray")]
22     #[fail(display = "NdarrayShapeError")]
23     NdarrayShapeError(#[cause] ndarray::ShapeError),
24     #[fail(display = "CPL error class: '{:?}', error number: '{}', error msg: '{}'", class, number, msg)]
25     CplError {
26         class: CPLErr::Type,
27         number: c_int,
28         msg: String
29     },
30     #[fail(display ="GDAL method '{}' returned a NULL pointer. Error msg: '{}'", method_name, msg)]
31     NullPointer {
32         method_name: &'static str,
33         msg: String
34     },
35     #[fail(display = "Can't cast to f64")]
36     CastToF64Error,
37     #[fail(display ="OGR method '{}' returned error: '{:?}'", method_name, err)]
38     OgrError {
39         err: OGRErr::Type,
40         method_name: &'static str
41     },
42     #[fail(display ="Unhandled type {:?} on OGR method {}", field_type, method_name)]
43     UnhandledFieldType {
44         field_type: OGRFieldType::Type,
45         method_name: &'static str
46     },
47     #[fail(display ="Invalid field name '{}' used on method {}", field_name, method_name)]
48     InvalidFieldName {
49         field_name: String,
50         method_name: &'static str
51     },
52     #[fail(display ="Invalid field index {} used on method {}", index, method_name)]
53     InvalidFieldIndex {
54         index: usize,
55         method_name: &'static str
56     },
57     #[fail(display ="Unlinked Geometry on method {}", method_name)]
58     UnlinkedGeometry {
59         method_name: &'static str
60     },
61     #[fail(display ="Invalid coordinate range while transforming points from {} to {}: {:?}", from, to, msg)]
62     InvalidCoordinateRange {
63         from: String,
64         to: String,
65         msg: Option<String>
66     }
67 
68 }
69 
70 impl Fail for Error {
cause(&self) -> Option<&Fail>71     fn cause(&self) -> Option<&Fail> {
72         self.inner.cause()
73     }
74 
backtrace(&self) -> Option<&Backtrace>75     fn backtrace(&self) -> Option<&Backtrace> {
76         self.inner.backtrace()
77     }
78 }
79 
80 impl fmt::Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result81     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82         fmt::Display::fmt(&self.inner, f)
83     }
84 }
85 
86 impl Error {
kind_ref(&self) -> &ErrorKind87     pub fn kind_ref(&self) -> &ErrorKind {
88         self.inner.get_context()
89     }
90 }
91 
92 impl From<ErrorKind> for Error {
from(kind: ErrorKind) -> Error93     fn from(kind: ErrorKind) -> Error {
94         Error { inner: Context::new(kind) }
95     }
96 }
97 
98 impl From<Context<ErrorKind>> for Error {
from(inner: Context<ErrorKind>) -> Error99     fn from(inner: Context<ErrorKind>) -> Error {
100         Error { inner }
101     }
102 }
103 
104 impl From<std::ffi::NulError> for Error {
from(err: std::ffi::NulError) -> Error105     fn from(err: std::ffi::NulError) -> Error {
106         Error { inner: Context::new(ErrorKind::FfiNulError(err)) }
107     }
108 }
109 
110 impl From<std::str::Utf8Error> for Error {
from(err: std::str::Utf8Error) -> Error111     fn from(err: std::str::Utf8Error) -> Error {
112         Error { inner: Context::new(ErrorKind::StrUtf8Error(err)) }
113     }
114 }
115 
116 #[cfg(feature = "ndarray")]
117 impl From<ndarray::ShapeError> for Error {
from(err: ndarray::ShapeError) -> Error118     fn from(err: ndarray::ShapeError) -> Error {
119         Error { inner: Context::new(ErrorKind::NdarrayShapeError(err)) }
120     }
121 }