1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
use thiserror::Error as DeriveError;
use crate::{H3Cell, Index, H3_MAX_RESOLUTION};
/// Errors as defines in [RFC] 4.0.0, extended with some custom errors of this wrapper library.
///
/// [RFC]: https://github.com/uber/h3/blob/master/dev-docs/RFCs/v4.0.0/error-handling-rfc.md
#[derive(Debug, DeriveError)]
pub enum Error {
/// The operation failed but a more specific error is not available
#[error("operation failed")]
Failed, // 1
/// Argument was outside of acceptable range (when a more specific error code is not available)
#[error("Argument was outside of acceptable range")]
Domain, // 2
/// Latitude or longitude arguments were outside of acceptable range
#[error("Latitude or longitude arguments were outside of acceptable range")]
LatLonDomain, // 3
/// Resolution argument was outside of acceptable range
#[error("Resolution argument was outside of acceptable range")]
ResDomain, // 4
/// H3Index cell argument was not valid
#[error("H3Index cell argument was not valid")]
CellInvalid, // 5
/// H3Index directed edge argument was not valid
#[error("H3Index directed edge argument was not valid")]
DirectedEdgeInvalid, // 6
/// H3Index undirected edge argument was not valid
#[error("H3Index undirected edge argument was not valid")]
UndirectedEdgeInvalid, // 7
/// H3Index vertex argument was not valid
#[error("H3Index vertex argument was not valid")]
VertexInvalid, // 8
/// Pentagon distortion was encountered which the algorithm could not handle it
#[error("Pentagon distortion was encountered")]
Pentagon, // 9
/// Duplicate input was encountered in the arguments and the algorithm could not handle it
#[error("Duplicate input was encountered in the arguments")]
DuplicateInput, // 10
/// H3Index cell arguments were not neighbors
#[error("H3Index cell arguments were not neighbors")]
NotNeighbors, // 11
/// H3Index cell arguments had incompatible resolutions
#[error("H3Index cell arguments had incompatible resolutions")]
ResMismatch, // 12
/// Necessary memory allocation failed
#[error("Necessary memory allocation failed")]
MemoryAlloc, // 13
/// Bounds of provided memory were not large enough
#[error("Bounds of provided memory were not large enough")]
MemoryBounds, // 14
/// Mode or flags argument was not valid.
#[error("Mode or flags argument was not valid")]
OptionInvalid, // 15
/// Unknown error code
#[error("Unknown h3 error code")]
UnknownError(u32),
/// Invalid H3 direction
#[error("Invalid H3 direction")]
DirectionInvalid(u8),
#[error("decompression error")]
DecompressionError(String),
}
impl Error {
/// returns the corresponding error for the given error code
const fn get_error(value: u32) -> Self {
match value {
1 => Self::Failed,
2 => Self::Domain,
3 => Self::LatLonDomain,
4 => Self::ResDomain,
5 => Self::CellInvalid,
6 => Self::DirectedEdgeInvalid,
7 => Self::UndirectedEdgeInvalid,
8 => Self::VertexInvalid,
9 => Self::Pentagon,
10 => Self::DuplicateInput,
11 => Self::NotNeighbors,
12 => Self::ResMismatch,
13 => Self::MemoryAlloc,
14 => Self::MemoryBounds,
15 => Self::OptionInvalid,
v => Self::UnknownError(v),
}
}
/// Checks if the H3 return value is an error
#[inline(always)]
pub const fn is_error(value: u32) -> bool {
value != 0
}
/// checks the return code of h3ron-h3-sys functions
#[inline(always)]
pub const fn check_returncode(value: u32) -> Result<(), Self> {
if Self::is_error(value) {
Err(Self::get_error(value))
} else {
Ok(())
}
}
}
/// Ensure two cells have the same resolution
pub fn check_same_resolution(cell0: H3Cell, cell1: H3Cell) -> Result<(), Error> {
let res0 = cell0.resolution();
let res1 = cell1.resolution();
if res0 == res1 {
Ok(())
} else {
Err(Error::ResMismatch)
}
}
/// Ensure the given resolution is valid
pub const fn check_valid_h3_resolution(h3_res: u8) -> Result<(), Error> {
if h3_res > H3_MAX_RESOLUTION {
Err(Error::ResDomain)
} else {
Ok(())
}
}