osm_io/osm/model/
element.rs

1use std::cmp::Ordering;
2
3use crate::osm::model::node::Node;
4use crate::osm::model::relation::Relation;
5use crate::osm::model::way::Way;
6
7#[derive(Debug, Clone)]
8pub enum Element {
9    Node {
10        node: Node,
11    },
12    Way {
13        way: Way,
14    },
15    Relation {
16        relation: Relation,
17    },
18    Sentinel,
19}
20
21impl Element {
22    pub fn same_type(e1: &Element, e2: &Element) -> bool {
23        match e1 {
24            Element::Node { .. } => {
25                match e2 {
26                    Element::Node { .. } => { true }
27                    Element::Way { .. } => { false }
28                    Element::Relation { .. } => { false }
29                    Element::Sentinel => { false }
30                }
31            }
32            Element::Way { .. } => {
33                match e2 {
34                    Element::Node { .. } => { false }
35                    Element::Way { .. } => { true }
36                    Element::Relation { .. } => { false }
37                    Element::Sentinel => { false }
38                }
39            }
40            Element::Relation { .. } => {
41                match e2 {
42                    Element::Node { .. } => { false }
43                    Element::Way { .. } => { false }
44                    Element::Relation { .. } => { true }
45                    Element::Sentinel => { false }
46                }
47            }
48            Element::Sentinel => {
49                match e2 {
50                    Element::Node { .. } => { false }
51                    Element::Way { .. } => { false }
52                    Element::Relation { .. } => { false }
53                    Element::Sentinel => { true }
54                }
55            }
56        }
57    }
58
59    pub fn is_node(&self) -> bool {
60        match self {
61            Element::Node { .. } => {
62                true
63            }
64            Element::Way { .. } => {
65                false
66            }
67            Element::Relation { .. } => {
68                false
69            }
70            Element::Sentinel => {
71                false
72            }
73        }
74    }
75
76    pub fn is_way(&self) -> bool {
77        match self {
78            Element::Node { .. } => {
79                false
80            }
81            Element::Way { .. } => {
82                true
83            }
84            Element::Relation { .. } => {
85                false
86            }
87            Element::Sentinel => {
88                false
89            }
90        }
91    }
92
93    pub fn is_relation(&self) -> bool {
94        match self {
95            Element::Node { .. } => {
96                false
97            }
98            Element::Way { .. } => {
99                false
100            }
101            Element::Relation { .. } => {
102                true
103            }
104            Element::Sentinel => {
105                false
106            }
107        }
108    }
109
110    pub fn is_sentinel(&self) -> bool {
111        match self {
112            Element::Node { .. } => {
113                false
114            }
115            Element::Way { .. } => {
116                false
117            }
118            Element::Relation { .. } => {
119                false
120            }
121            Element::Sentinel => {
122                true
123            }
124        }
125    }
126}
127
128impl Eq for Element {}
129
130impl PartialEq<Self> for Element {
131    fn eq(&self, other: &Self) -> bool {
132        match self {
133            Element::Node { node } => {
134                let id = node.id();
135                let version = node.version();
136                match other {
137                    Element::Node { node } => {
138                        id.eq(&node.id()) && version.eq(&node.version())
139                    }
140                    Element::Way { .. } => {
141                        false
142                    }
143                    Element::Relation { .. } => {
144                        false
145                    }
146                    Element::Sentinel => {
147                        false
148                    }
149                }
150            }
151            Element::Way { way } => {
152                let id = way.id();
153                let version = way.version();
154                match other {
155                    Element::Node { .. } => {
156                        false
157                    }
158                    Element::Way { way } => {
159                        id.eq(&way.id()) && version.eq(&way.version())
160                    }
161                    Element::Relation { .. } => {
162                        false
163                    }
164                    Element::Sentinel => {
165                        false
166                    }
167                }
168            }
169            Element::Relation { relation } => {
170                let id = relation.id();
171                let version = relation.version();
172                match other {
173                    Element::Node { .. } => {
174                        false
175                    }
176                    Element::Way { .. } => {
177                        false
178                    }
179                    Element::Relation { relation } => {
180                        id.eq(&relation.id()) && version.eq(&relation.version())
181                    }
182                    Element::Sentinel => {
183                        false
184                    }
185                }
186            }
187            Element::Sentinel => {
188                match other {
189                    Element::Node { .. } => {
190                        false
191                    }
192                    Element::Way { .. } => {
193                        false
194                    }
195                    Element::Relation { .. } => {
196                        false
197                    }
198                    Element::Sentinel => {
199                        true
200                    }
201                }
202            }
203        }
204    }
205}
206
207impl PartialOrd<Self> for Element {
208    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
209        Some(self.cmp(other))
210    }
211}
212
213impl Ord for Element {
214    fn cmp(&self, other: &Self) -> Ordering {
215        match self {
216            Element::Node { node } => {
217                let id = node.id();
218                let version = node.version();
219                match other {
220                    Element::Node { node } => {
221                        match id.cmp(&node.id()) {
222                            Ordering::Less => {
223                                Ordering::Less
224                            }
225                            Ordering::Equal => {
226                                version.cmp(&node.version())
227                            }
228                            Ordering::Greater => {
229                                Ordering::Greater
230                            }
231                        }
232                    }
233                    Element::Way { .. } => {
234                        Ordering::Less
235                    }
236                    Element::Relation { .. } => {
237                        Ordering::Less
238                    }
239                    Element::Sentinel => {
240                        Ordering::Less
241                    }
242                }
243            }
244            Element::Way { way } => {
245                let id = way.id();
246                let version = way.version();
247                match other {
248                    Element::Node { .. } => {
249                        Ordering::Greater
250                    }
251                    Element::Way { way } => {
252                        match id.cmp(&way.id()) {
253                            Ordering::Less => {
254                                Ordering::Less
255                            }
256                            Ordering::Equal => {
257                                version.cmp(&way.version())
258                            }
259                            Ordering::Greater => {
260                                Ordering::Greater
261                            }
262                        }
263                    }
264                    Element::Relation { .. } => {
265                        Ordering::Less
266                    }
267                    Element::Sentinel => {
268                        Ordering::Less
269                    }
270                }
271            }
272            Element::Relation { relation } => {
273                let id = relation.id();
274                let version = relation.version();
275                match other {
276                    Element::Node { .. } => {
277                        Ordering::Greater
278                    }
279                    Element::Way { .. } => {
280                        Ordering::Greater
281                    }
282                    Element::Relation { relation } => {
283                        match id.cmp(&relation.id()) {
284                            Ordering::Less => {
285                                Ordering::Less
286                            }
287                            Ordering::Equal => {
288                                version.cmp(&relation.version())
289                            }
290                            Ordering::Greater => {
291                                Ordering::Greater
292                            }
293                        }
294                    }
295                    Element::Sentinel => {
296                        Ordering::Less
297                    }
298                }
299            }
300            Element::Sentinel => {
301                match other {
302                    Element::Node { .. } => {
303                        Ordering::Less
304                    }
305                    Element::Way { .. } => {
306                        Ordering::Less
307                    }
308                    Element::Relation { .. } => {
309                        Ordering::Less
310                    }
311                    Element::Sentinel => {
312                        Ordering::Equal
313                    }
314                }
315            }
316        }
317    }
318}