1#![warn(missing_docs)]
4
5use crate::{CRS, MyError};
10use core::fmt;
11use std::num::NonZero;
12
13pub const EPSG_4326: SRID = SRID(4326);
15
16#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
19#[allow(clippy::upper_case_acronyms)]
20pub struct SRID(i32);
21
22impl TryFrom<i32> for SRID {
24 type Error = MyError;
25
26 fn try_from(value: i32) -> Result<Self, Self::Error> {
27 match value {
30 x if x == -1 || x == 0 => Ok(Self(x)),
31 x => {
32 let code = usize::try_from(value)?;
34 let _ = CRS::from_epsg(
35 NonZero::new(code)
36 .ok_or(MyError::Runtime("Expected a non-zero EPSG code".into()))?,
37 )?;
38 Ok(Self(x))
39 }
40 }
41 }
42}
43
44impl TryFrom<usize> for SRID {
46 type Error = MyError;
47
48 fn try_from(value: usize) -> Result<Self, Self::Error> {
49 match value {
50 0 => Ok(Self(0)),
51 x => {
52 let _ = CRS::from_epsg(
54 NonZero::new(value)
55 .ok_or(MyError::Runtime("Expected a non-zero EPSG code".into()))?,
56 )?;
57 Ok(Self(x.try_into()?))
58 }
59 }
60 }
61}
62
63impl fmt::Display for SRID {
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 match self.0 {
66 -1 => write!(f, "Undefined (Cartesian)"),
67 0 => write!(f, "Undefined (geographic)"),
68 x => write!(f, "EPSG:{x}"),
69 }
70 }
71}
72
73impl SRID {
74 pub(crate) fn as_usize(&self) -> Result<usize, MyError> {
75 let it = usize::try_from(self.0)?;
76 Ok(it)
77 }
78}