Skip to main content

egml_core/model/geometry/
abstract_geometry.rs

1use crate::model::base::{AbstractGml, AsAbstractGml, AsAbstractGmlMut};
2
3/// Base data shared by all GML geometry types ([OGC 07-036 ยง10.1.3.1](https://docs.ogc.org/is/07-036/07-036.pdf)).
4///
5/// Embeds [`AbstractGml`] and is in turn embedded by every concrete and
6/// abstract geometry.
7#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
8pub struct AbstractGeometry {
9    pub abstract_gml: AbstractGml,
10    srs_name: Option<String>,
11    srs_dimension: Option<u32>,
12}
13
14impl AbstractGeometry {
15    /// Creates a new `AbstractGeometry` wrapping the provided GML base data.
16    pub fn new() -> Self {
17        Self {
18            abstract_gml: AbstractGml::default(),
19            srs_name: None,
20            srs_dimension: None,
21        }
22    }
23
24    pub fn from_abstract_gml(abstract_gml: AbstractGml) -> Self {
25        Self {
26            abstract_gml,
27            srs_name: None,
28            srs_dimension: None,
29        }
30    }
31}
32
33/// Object-safe read accessor for [`AbstractGeometry`] fields.
34pub trait AsAbstractGeometry: AsAbstractGml {
35    /// Returns a reference to the embedded [`AbstractGeometry`] base data.
36    fn abstract_geometry(&self) -> &AbstractGeometry;
37
38    fn srs_name(&self) -> Option<&String> {
39        self.abstract_geometry().srs_name.as_ref()
40    }
41
42    fn srs_dimension(&self) -> Option<u32> {
43        self.abstract_geometry().srs_dimension
44    }
45}
46
47/// Mutable companion to [`AsAbstractGeometry`].
48pub trait AsAbstractGeometryMut: AsAbstractGeometry + AsAbstractGmlMut {
49    /// Returns a mutable reference to the embedded [`AbstractGeometry`] base data.
50    fn abstract_geometry_mut(&mut self) -> &mut AbstractGeometry;
51
52    fn set_srs_name(&mut self, srs_name: impl Into<String>) {
53        self.abstract_geometry_mut().srs_name = Some(srs_name.into());
54    }
55
56    fn set_srs_name_opt(&mut self, srs_name: Option<String>) {
57        self.abstract_geometry_mut().srs_name = srs_name;
58    }
59
60    fn clear_srs_name(&mut self) {
61        self.abstract_geometry_mut().srs_name = None;
62    }
63
64    fn set_srs_dimension(&mut self, srs_dimension: u32) {
65        self.abstract_geometry_mut().srs_dimension = Some(srs_dimension);
66    }
67
68    fn set_srs_dimension_opt(&mut self, srs_dimension: Option<u32>) {
69        self.abstract_geometry_mut().srs_dimension = srs_dimension;
70    }
71
72    fn clear_srs_dimension(&mut self) {
73        self.abstract_geometry_mut().srs_dimension = None;
74    }
75}
76
77impl AsAbstractGeometry for AbstractGeometry {
78    fn abstract_geometry(&self) -> &AbstractGeometry {
79        self
80    }
81}
82
83impl AsAbstractGeometryMut for AbstractGeometry {
84    fn abstract_geometry_mut(&mut self) -> &mut AbstractGeometry {
85        self
86    }
87}
88
89#[macro_export]
90macro_rules! impl_abstract_geometry_traits {
91    ($type:ty) => {
92        $crate::impl_abstract_gml_traits!($type);
93
94        impl $crate::model::base::AsAbstractGml for $type {
95            fn abstract_gml(&self) -> &$crate::model::base::AbstractGml {
96                &<$type as $crate::model::geometry::AsAbstractGeometry>::abstract_geometry(self)
97                    .abstract_gml
98            }
99        }
100    };
101}
102
103#[macro_export]
104macro_rules! impl_abstract_geometry_mut_traits {
105    ($type:ty) => {
106        $crate::impl_abstract_gml_mut_traits!($type);
107
108        impl $crate::model::base::AsAbstractGmlMut for $type {
109            fn abstract_gml_mut(&mut self) -> &mut $crate::model::base::AbstractGml {
110                &mut <$type as $crate::model::geometry::AsAbstractGeometryMut>::abstract_geometry_mut(self)
111                    .abstract_gml
112            }
113        }
114    };
115}
116
117impl_abstract_geometry_traits!(AbstractGeometry);
118impl_abstract_geometry_mut_traits!(AbstractGeometry);