async-geotiff 0.13.0

Async COG → XYZ tile renderer (pure Rust, no GDAL)
Documentation
/// Coordinate reference system identifier.
///
/// Note: `proj::Proj::new_known_crs("EPSG:4326", _, None)` normalises EPSG:4326
/// to `(lon, lat)` order, **not** `(lat, lon)` like pyproj 3+. All callers in
/// this crate work in `(x=lon, y=lat)` order to match.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Crs(String);

impl Crs {
    /// Construct an `EPSG:<code>` identifier without checking the CRS registry.
    pub fn epsg(code: u32) -> Self {
        Self(format!("EPSG:{}", code))
    }

    /// Store a CRS definition; transformation construction performs validation.
    pub fn new(s: impl Into<String>) -> Self {
        Self(s.into())
    }

    /// Borrow the original CRS identifier or definition.
    pub fn as_str(&self) -> &str {
        &self.0
    }
}

impl std::fmt::Display for Crs {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(&self.0)
    }
}

impl std::str::FromStr for Crs {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(Self::new(s))
    }
}

impl From<&str> for Crs {
    fn from(value: &str) -> Self {
        Self::new(value)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn epsg_builds_string() {
        assert_eq!(Crs::epsg(3857).as_str(), "EPSG:3857");
    }

    #[test]
    fn equality_is_string_based() {
        assert_eq!(Crs::epsg(4326), Crs::new("EPSG:4326"));
        assert_ne!(Crs::epsg(4326), Crs::epsg(3857));
    }
}