1use core::fmt;
4
5#[non_exhaustive]
9#[derive(Clone, Debug, PartialEq)]
10pub enum Error {
11 LatOutOfRange {
13 found: f64,
15 },
16 LonOutOfRange {
18 found: f64,
20 },
21 ZoneOutOfRange {
23 found: u8,
25 },
26 EastingOutOfRange {
28 found: f64,
30 },
31 NorthingOutOfRange {
33 found: f64,
35 },
36 PrecisionOutOfRange {
38 found: u8,
40 },
41 OutsideMgrsExtent {
43 easting: f64,
45 northing: f64,
47 },
48 Parse(ParseErrorKind),
50}
51
52#[non_exhaustive]
54#[derive(Clone, Copy, Debug, PartialEq, Eq)]
55pub enum ParseErrorKind {
56 Empty,
58 GridZoneOnly,
61 BadZoneNumber,
63 BadBandLetter,
65 BadSquareLetters,
67 SquareZoneMismatch,
69 SquareBandMismatch,
71 OddDigitCount,
73 TooManyDigits,
75 NonAsciiOrWhitespace,
77 TrailingInput,
79}
80
81impl fmt::Display for Error {
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 match self {
84 Error::LatOutOfRange { found } => {
85 write!(f, "latitude {found} is not a finite value in [-90, 90]")
86 }
87 Error::LonOutOfRange { found } => {
88 write!(f, "longitude {found} is not finite")
89 }
90 Error::ZoneOutOfRange { found } => {
91 write!(f, "zone {found} is outside 1 to 60")
92 }
93 Error::EastingOutOfRange { found } => {
94 write!(f, "easting {found} m is outside the transfer range")
95 }
96 Error::NorthingOutOfRange { found } => {
97 write!(f, "northing {found} m is outside the transfer range")
98 }
99 Error::PrecisionOutOfRange { found } => {
100 write!(f, "precision {found} is outside 0 to 11")
101 }
102 Error::OutsideMgrsExtent { easting, northing } => {
103 write!(
104 f,
105 "easting {easting} m, northing {northing} m is outside the MGRS grid coverage"
106 )
107 }
108 Error::Parse(kind) => write!(f, "invalid MGRS string: {kind}"),
109 }
110 }
111}
112
113impl fmt::Display for ParseErrorKind {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 let msg = match self {
116 ParseErrorKind::Empty => "empty string",
117 ParseErrorKind::GridZoneOnly => "grid-zone-only reference is not supported",
118 ParseErrorKind::BadZoneNumber => "zone number is not in 1 to 60",
119 ParseErrorKind::BadBandLetter => "band letter is not C to X (I and O excluded)",
120 ParseErrorKind::BadSquareLetters => "100 km square letters are not in the alphabets",
121 ParseErrorKind::SquareZoneMismatch => "square letters do not belong to this zone",
122 ParseErrorKind::SquareBandMismatch => {
123 "square letters imply a northing outside this band"
124 }
125 ParseErrorKind::OddDigitCount => "digit block has an odd number of digits",
126 ParseErrorKind::TooManyDigits => "digit block has more than 22 digits",
127 ParseErrorKind::NonAsciiOrWhitespace => "non-ASCII byte or internal whitespace",
128 ParseErrorKind::TrailingInput => "unexpected character after the square letters",
129 };
130 f.write_str(msg)
131 }
132}
133
134impl std::error::Error for Error {}