Skip to main content

egml_core/model/base/
abstract_gml.rs

1use crate::model::base::Id;
2
3/// Base data shared by every GML object (ISO 19136 ยง7.2.2, `gml:AbstractGMLType`).
4///
5/// Every GML object carries an optional stable [`Id`] and zero-or-more human-readable
6/// name strings.  Concrete geometry and feature types embed `AbstractGml` and
7/// expose it through the [`AsAbstractGml`] trait.
8#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
9pub struct AbstractGml {
10    /// Optional stable identifier for this GML object.
11    pub id: Option<Id>,
12    /// Human-readable names associated with this GML object.
13    pub name: Vec<String>,
14}
15
16impl AbstractGml {
17    /// Creates a new `AbstractGml` with no id and no names.
18    ///
19    /// # Examples
20    ///
21    /// ```rust
22    /// use egml_core::model::base::AbstractGml;
23    ///
24    /// let gml = AbstractGml::new();
25    /// assert!(gml.id.is_none());
26    /// assert!(gml.name.is_empty());
27    /// ```
28    pub fn new() -> Self {
29        Self::default()
30    }
31
32    /// Creates a new `AbstractGml` pre-populated with the given `id`.
33    ///
34    /// # Examples
35    ///
36    /// ```rust
37    /// use egml_core::model::base::{AbstractGml, Id};
38    ///
39    /// let id = Id::from_hashed_string("my-object");
40    /// let gml = AbstractGml::with_id(id);
41    /// assert!(gml.id.is_some());
42    /// ```
43    pub fn with_id(id: Id) -> Self {
44        Self {
45            id: Some(id),
46            ..Default::default()
47        }
48    }
49
50    /// Creates a new `AbstractGml` with an optional id.
51    ///
52    /// Equivalent to [`with_id`](Self::with_id) when `id` is `Some`, and to
53    /// [`new`](Self::new) when `id` is `None`.
54    pub fn with_optional_id(id: Option<Id>) -> Self {
55        Self {
56            id,
57            ..Default::default()
58        }
59    }
60}
61
62/// Object-safe read accessor for [`AbstractGml`] fields.
63///
64/// Implemented by all GML object types.  The default methods delegate to
65/// [`abstract_gml()`](Self::abstract_gml), so implementors only need to
66/// provide that single method.
67pub trait AsAbstractGml {
68    /// Returns a reference to the embedded [`AbstractGml`] base data.
69    fn abstract_gml(&self) -> &AbstractGml;
70
71    /// Returns the optional identifier of this GML object.
72    fn id(&self) -> Option<&Id> {
73        self.abstract_gml().id.as_ref()
74    }
75
76    /// Returns the names of this GML object.
77    fn name(&self) -> &[String] {
78        &self.abstract_gml().name
79    }
80}
81
82/// Mutable companion to [`AsAbstractGml`].
83///
84/// Implemented by all GML object types that expose mutable access to their
85/// base data.
86pub trait AsAbstractGmlMut: AsAbstractGml {
87    /// Returns a mutable reference to the embedded [`AbstractGml`] base data.
88    fn abstract_gml_mut(&mut self) -> &mut AbstractGml;
89
90    /// Sets or clears the identifier of this GML object.
91    fn set_id(&mut self, id: Option<Id>) {
92        self.abstract_gml_mut().id = id;
93    }
94}
95
96impl AsAbstractGml for AbstractGml {
97    fn abstract_gml(&self) -> &AbstractGml {
98        self
99    }
100}
101
102impl AsAbstractGmlMut for AbstractGml {
103    fn abstract_gml_mut(&mut self) -> &mut AbstractGml {
104        self
105    }
106}