tg_geom/
geom_type.rs

1//! OGC Simple Feature geometry types.
2
3use core::ffi::CStr;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6#[repr(u32)]
7pub enum GeomType {
8    Point = 1,
9    LineString = 2,
10    Polygon = 3,
11    MultiPoint = 4,
12    MultiLineString = 5,
13    MultiPolygon = 6,
14    GeometryCollection = 7,
15}
16
17impl GeomType {
18    pub fn as_str(self) -> &'static str {
19        let ptr = unsafe { tg_geom_sys::tg_geom_type_string(self.into()) };
20        if ptr.is_null() {
21            "Unknown"
22        } else {
23            unsafe { CStr::from_ptr(ptr) }.to_str().unwrap_or("Unknown")
24        }
25    }
26}
27
28impl From<tg_geom_sys::tg_geom_type> for GeomType {
29    fn from(t: tg_geom_sys::tg_geom_type) -> Self {
30        match t {
31            tg_geom_sys::tg_geom_type_TG_POINT => GeomType::Point,
32            tg_geom_sys::tg_geom_type_TG_LINESTRING => GeomType::LineString,
33            tg_geom_sys::tg_geom_type_TG_POLYGON => GeomType::Polygon,
34            tg_geom_sys::tg_geom_type_TG_MULTIPOINT => GeomType::MultiPoint,
35            tg_geom_sys::tg_geom_type_TG_MULTILINESTRING => GeomType::MultiLineString,
36            tg_geom_sys::tg_geom_type_TG_MULTIPOLYGON => GeomType::MultiPolygon,
37            tg_geom_sys::tg_geom_type_TG_GEOMETRYCOLLECTION => GeomType::GeometryCollection,
38            _ => unreachable!("unknown geometry type: {t}"),
39        }
40    }
41}
42
43impl From<GeomType> for tg_geom_sys::tg_geom_type {
44    fn from(t: GeomType) -> Self {
45        match t {
46            GeomType::Point => tg_geom_sys::tg_geom_type_TG_POINT,
47            GeomType::LineString => tg_geom_sys::tg_geom_type_TG_LINESTRING,
48            GeomType::Polygon => tg_geom_sys::tg_geom_type_TG_POLYGON,
49            GeomType::MultiPoint => tg_geom_sys::tg_geom_type_TG_MULTIPOINT,
50            GeomType::MultiLineString => tg_geom_sys::tg_geom_type_TG_MULTILINESTRING,
51            GeomType::MultiPolygon => tg_geom_sys::tg_geom_type_TG_MULTIPOLYGON,
52            GeomType::GeometryCollection => tg_geom_sys::tg_geom_type_TG_GEOMETRYCOLLECTION,
53        }
54    }
55}
56
57impl core::fmt::Display for GeomType {
58    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
59        write!(f, "{}", self.as_str())
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66
67    #[test]
68    fn test_geom_type_as_str() {
69        assert_eq!(GeomType::Point.as_str(), "Point");
70        assert_eq!(GeomType::LineString.as_str(), "LineString");
71        assert_eq!(GeomType::Polygon.as_str(), "Polygon");
72        assert_eq!(GeomType::MultiPoint.as_str(), "MultiPoint");
73        assert_eq!(GeomType::MultiLineString.as_str(), "MultiLineString");
74        assert_eq!(GeomType::MultiPolygon.as_str(), "MultiPolygon");
75        assert_eq!(GeomType::GeometryCollection.as_str(), "GeometryCollection");
76    }
77
78    #[test]
79    fn test_geom_type_repr() {
80        assert_eq!(GeomType::Point as u32, 1);
81        assert_eq!(GeomType::LineString as u32, 2);
82        assert_eq!(GeomType::Polygon as u32, 3);
83        assert_eq!(GeomType::MultiPoint as u32, 4);
84        assert_eq!(GeomType::MultiLineString as u32, 5);
85        assert_eq!(GeomType::MultiPolygon as u32, 6);
86        assert_eq!(GeomType::GeometryCollection as u32, 7);
87    }
88
89    #[test]
90    fn test_geom_type_sys_roundtrip() {
91        let types = [
92            GeomType::Point,
93            GeomType::LineString,
94            GeomType::Polygon,
95            GeomType::MultiPoint,
96            GeomType::MultiLineString,
97            GeomType::MultiPolygon,
98            GeomType::GeometryCollection,
99        ];
100        for t in &types {
101            let sys_type: tg_geom_sys::tg_geom_type = (*t).into();
102            let back: GeomType = sys_type.into();
103            assert_eq!(*t, back);
104        }
105    }
106
107    #[test]
108    fn test_geom_type_display() {
109        assert_eq!(format!("{}", GeomType::Point), "Point");
110        assert_eq!(format!("{}", GeomType::LineString), "LineString");
111        assert_eq!(format!("{}", GeomType::Polygon), "Polygon");
112        assert_eq!(format!("{}", GeomType::MultiPoint), "MultiPoint");
113        assert_eq!(format!("{}", GeomType::MultiLineString), "MultiLineString");
114        assert_eq!(format!("{}", GeomType::MultiPolygon), "MultiPolygon");
115        assert_eq!(
116            format!("{}", GeomType::GeometryCollection),
117            "GeometryCollection"
118        );
119    }
120
121    #[test]
122    fn test_geom_type_debug() {
123        let debug_str = format!("{:?}", GeomType::Point);
124        assert!(debug_str.contains("Point"));
125    }
126
127    #[test]
128    fn test_geom_type_copy() {
129        let t1 = GeomType::Polygon;
130        let t2 = t1;
131        assert_eq!(t1, t2);
132    }
133
134    #[test]
135    fn test_geom_type_eq() {
136        assert_eq!(GeomType::Point, GeomType::Point);
137        assert_ne!(GeomType::Point, GeomType::LineString);
138    }
139}