use thiserror::Error;
#[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum ProjError {
#[error("invalid PROJ string syntax or operation")]
InvalidOp,
#[error("invalid PROJ string syntax")]
WrongSyntax,
#[error("missing required operation parameter")]
MissingArg,
#[error("one of the operation parameters has an illegal value")]
IllegalArgValue,
#[error("mutually exclusive arguments")]
MutuallyExclusiveArgs,
#[error("file not found or with invalid content")]
FileNotFound,
#[error("value does not correspond to an ellipsoid")]
NotEllipsoid,
#[error("generic error of coordinate transformation")]
CoordTransfm,
#[error("invalid coordinate")]
InvalidCoord,
#[error("coordinate outside projection domain")]
OutsideProjectionDomain,
#[error("no operation found matching criteria")]
NoOperation,
#[error("point to transform falls outside grid or subgrid")]
OutsideGrid,
#[error("point to transform falls in a grid cell that evaluates to nodata")]
GridAtNodata,
#[error("iterative algorithm did not converge")]
NoConvergence,
#[error("missing required time coordinate")]
MissingTime,
#[error("other error")]
Other,
#[error("error caused by incorrect use of PROJ API")]
ApiMisuse,
#[error("no inverse operation")]
NoInverseOp,
#[error("failure when accessing a network resource")]
NetworkError,
}
impl ProjError {
pub fn code(&self) -> i32 {
match self {
ProjError::InvalidOp => 1024,
ProjError::WrongSyntax => 1025,
ProjError::MissingArg => 1026,
ProjError::IllegalArgValue => 1027,
ProjError::MutuallyExclusiveArgs => 1028,
ProjError::FileNotFound => 1029,
ProjError::NotEllipsoid => 1027,
ProjError::CoordTransfm => 2048,
ProjError::InvalidCoord => 2049,
ProjError::OutsideProjectionDomain => 2050,
ProjError::NoOperation => 2051,
ProjError::OutsideGrid => 2052,
ProjError::GridAtNodata => 2053,
ProjError::NoConvergence => 2054,
ProjError::MissingTime => 2055,
ProjError::Other => 4096,
ProjError::ApiMisuse => 4097,
ProjError::NoInverseOp => 4098,
ProjError::NetworkError => 4099,
}
}
}
pub type ProjResult<T> = Result<T, ProjError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn invalid_op_code() {
assert_eq!(ProjError::InvalidOp.code(), 1024);
}
#[test]
fn wrong_syntax_code() {
assert_eq!(ProjError::WrongSyntax.code(), 1025);
}
#[test]
fn missing_arg_code() {
assert_eq!(ProjError::MissingArg.code(), 1026);
}
#[test]
fn illegal_arg_value_code() {
assert_eq!(ProjError::IllegalArgValue.code(), 1027);
}
#[test]
fn mutually_exclusive_args_code() {
assert_eq!(ProjError::MutuallyExclusiveArgs.code(), 1028);
}
#[test]
fn file_not_found_code() {
assert_eq!(ProjError::FileNotFound.code(), 1029);
}
#[test]
fn not_ellipsoid_code() {
assert_eq!(ProjError::NotEllipsoid.code(), 1027);
}
#[test]
fn coord_transfm_code() {
assert_eq!(ProjError::CoordTransfm.code(), 2048);
}
#[test]
fn invalid_coord_code() {
assert_eq!(ProjError::InvalidCoord.code(), 2049);
}
#[test]
fn outside_projection_domain_code() {
assert_eq!(ProjError::OutsideProjectionDomain.code(), 2050);
}
#[test]
fn no_operation_code() {
assert_eq!(ProjError::NoOperation.code(), 2051);
}
#[test]
fn outside_grid_code() {
assert_eq!(ProjError::OutsideGrid.code(), 2052);
}
#[test]
fn grid_at_nodata_code() {
assert_eq!(ProjError::GridAtNodata.code(), 2053);
}
#[test]
fn no_convergence_code() {
assert_eq!(ProjError::NoConvergence.code(), 2054);
}
#[test]
fn missing_time_code() {
assert_eq!(ProjError::MissingTime.code(), 2055);
}
#[test]
fn other_code() {
assert_eq!(ProjError::Other.code(), 4096);
}
#[test]
fn api_misuse_code() {
assert_eq!(ProjError::ApiMisuse.code(), 4097);
}
#[test]
fn no_inverse_op_code() {
assert_eq!(ProjError::NoInverseOp.code(), 4098);
}
#[test]
fn network_error_code() {
assert_eq!(ProjError::NetworkError.code(), 4099);
}
#[test]
fn display_messages_non_empty() {
assert!(!ProjError::InvalidCoord.to_string().is_empty());
assert!(!ProjError::OutsideProjectionDomain.to_string().is_empty());
}
#[test]
fn proj_result_alias_works() {
let ok: ProjResult<i32> = Ok(7);
let err: ProjResult<i32> = Err(ProjError::Other);
assert_eq!(ok, Ok(7));
assert_eq!(err, Err(ProjError::Other));
}
}