osm_io/osm/model/
element.rs1use 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}