osmio/obj_types/
rc_types.rs

1use super::*;
2use crate::{Lat, Lon, OSMObj, OSMObjectType, ObjId, TimestampFormat};
3use std::rc::Rc;
4
5macro_rules! func_call_inner_get {
6    ($slf:ident, $name:ident) => {
7        match $slf {
8            RcOSMObj::Node(x) => x.$name(),
9            RcOSMObj::Way(x) => x.$name(),
10            RcOSMObj::Relation(x) => x.$name(),
11        }
12    };
13}
14
15macro_rules! func_call_inner_set {
16    ($slf:ident, $name:ident, $val:ident) => {
17        match $slf {
18            RcOSMObj::Node(x) => x.$name($val),
19            RcOSMObj::Way(x) => x.$name($val),
20            RcOSMObj::Relation(x) => x.$name($val),
21        };
22    };
23}
24
25#[derive(Clone, PartialEq, Debug)]
26pub struct RcNode {
27    pub(crate) _id: ObjId,
28    pub(crate) _version: Option<u32>,
29    pub(crate) _deleted: bool,
30    pub(crate) _changeset_id: Option<u32>,
31    pub(crate) _timestamp: Option<TimestampFormat>,
32    pub(crate) _uid: Option<u32>,
33    pub(crate) _user: Option<Rc<str>>,
34    pub(crate) _tags: Option<Vec<(Rc<str>, Rc<str>)>>,
35
36    pub(crate) _lat_lon: Option<(Lat, Lon)>,
37}
38
39#[derive(Clone, PartialEq, Debug)]
40pub struct RcWay {
41    pub(crate) _id: ObjId,
42    pub(crate) _version: Option<u32>,
43    pub(crate) _deleted: bool,
44    pub(crate) _changeset_id: Option<u32>,
45    pub(crate) _timestamp: Option<TimestampFormat>,
46    pub(crate) _uid: Option<u32>,
47    pub(crate) _user: Option<Rc<str>>,
48    pub(crate) _tags: Vec<(Rc<str>, Rc<str>)>,
49
50    pub(crate) _nodes: Vec<ObjId>,
51}
52
53#[derive(Clone, PartialEq, Debug)]
54pub struct RcRelation {
55    pub(crate) _id: ObjId,
56    pub(crate) _version: Option<u32>,
57    pub(crate) _deleted: bool,
58    pub(crate) _changeset_id: Option<u32>,
59    pub(crate) _timestamp: Option<TimestampFormat>,
60    pub(crate) _uid: Option<u32>,
61    pub(crate) _user: Option<Rc<str>>,
62    pub(crate) _tags: Vec<(Rc<str>, Rc<str>)>,
63
64    pub(crate) _members: Vec<(OSMObjectType, ObjId, Rc<str>)>,
65}
66
67#[derive(Clone, PartialEq, Debug)]
68pub enum RcOSMObj {
69    Node(RcNode),
70    Way(RcWay),
71    Relation(RcRelation),
72}
73
74impl OSMObjBase for RcOSMObj {
75    fn id(&self) -> ObjId {
76        func_call_inner_get!(self, id)
77    }
78    fn version(&self) -> Option<u32> {
79        func_call_inner_get!(self, version)
80    }
81    fn deleted(&self) -> bool {
82        func_call_inner_get!(self, deleted)
83    }
84    fn changeset_id(&self) -> Option<u32> {
85        func_call_inner_get!(self, changeset_id)
86    }
87    fn timestamp(&self) -> &Option<TimestampFormat> {
88        func_call_inner_get!(self, timestamp)
89    }
90    fn uid(&self) -> Option<u32> {
91        func_call_inner_get!(self, uid)
92    }
93    fn user(&self) -> Option<&str> {
94        func_call_inner_get!(self, user)
95    }
96
97    fn set_id(&mut self, val: impl Into<ObjId>) {
98        func_call_inner_set!(self, set_id, val);
99    }
100    fn set_version(&mut self, val: impl Into<Option<u32>>) {
101        func_call_inner_set!(self, set_version, val);
102    }
103    fn set_deleted(&mut self, val: bool) {
104        func_call_inner_set!(self, set_deleted, val);
105    }
106    fn set_changeset_id(&mut self, val: impl Into<Option<u32>>) {
107        func_call_inner_set!(self, set_changeset_id, val);
108    }
109    fn set_timestamp(&mut self, val: impl Into<Option<TimestampFormat>>) {
110        func_call_inner_set!(self, set_timestamp, val);
111    }
112    fn set_uid(&mut self, val: impl Into<Option<u32>>) {
113        func_call_inner_set!(self, set_uid, val);
114    }
115    fn set_user<'a>(&mut self, val: impl Into<Option<&'a str>>) {
116        func_call_inner_set!(self, set_user, val);
117    }
118
119    fn tags<'a>(&'a self) -> Box<dyn ExactSizeIterator<Item = (&'a str, &'a str)> + 'a> {
120        match self {
121            RcOSMObj::Node(x) => x.tags(),
122            RcOSMObj::Way(x) => x.tags(),
123            RcOSMObj::Relation(x) => x.tags(),
124        }
125    }
126
127    fn num_tags(&self) -> usize {
128        match self {
129            RcOSMObj::Node(x) => x._tags.as_ref().map_or(0, |t| t.len()),
130            RcOSMObj::Way(x) => x._tags.len(),
131            RcOSMObj::Relation(x) => x._tags.len(),
132        }
133    }
134    fn untagged(&self) -> bool {
135        match self {
136            RcOSMObj::Node(x) => x._tags.as_ref().map_or(true, |t| t.is_empty()),
137            RcOSMObj::Way(x) => x._tags.is_empty(),
138            RcOSMObj::Relation(x) => x._tags.is_empty(),
139        }
140    }
141
142    fn tag(&self, key: impl AsRef<str>) -> Option<&str> {
143        match self {
144            RcOSMObj::Node(x) => x.tag(key),
145            RcOSMObj::Way(x) => x.tag(key),
146            RcOSMObj::Relation(x) => x.tag(key),
147        }
148    }
149
150    fn set_tag(&mut self, key: impl AsRef<str>, value: impl Into<String>) {
151        match self {
152            RcOSMObj::Node(x) => x.set_tag(key, value),
153            RcOSMObj::Way(x) => x.set_tag(key, value),
154            RcOSMObj::Relation(x) => x.set_tag(key, value),
155        }
156    }
157
158    fn unset_tag(&mut self, key: impl AsRef<str>) {
159        match self {
160            RcOSMObj::Node(x) => x.unset_tag(key),
161            RcOSMObj::Way(x) => x.unset_tag(key),
162            RcOSMObj::Relation(x) => x.unset_tag(key),
163        }
164    }
165
166    fn object_type(&self) -> OSMObjectType {
167        match self {
168            RcOSMObj::Node(_) => OSMObjectType::Node,
169            RcOSMObj::Way(_) => OSMObjectType::Way,
170            RcOSMObj::Relation(_) => OSMObjectType::Relation,
171        }
172    }
173}
174
175impl OSMObj for RcOSMObj {
176    type Node = RcNode;
177    type Way = RcWay;
178    type Relation = RcRelation;
179
180    fn into_node(self) -> Option<RcNode> {
181        if let RcOSMObj::Node(n) = self {
182            Some(n)
183        } else {
184            None
185        }
186    }
187
188    fn into_way(self) -> Option<RcWay> {
189        if let RcOSMObj::Way(w) = self {
190            Some(w)
191        } else {
192            None
193        }
194    }
195
196    fn into_relation(self) -> Option<RcRelation> {
197        if let RcOSMObj::Relation(r) = self {
198            Some(r)
199        } else {
200            None
201        }
202    }
203
204    fn as_node(&self) -> Option<&RcNode> {
205        if let RcOSMObj::Node(n) = self {
206            Some(n)
207        } else {
208            None
209        }
210    }
211
212    fn as_way(&self) -> Option<&RcWay> {
213        if let RcOSMObj::Way(w) = self {
214            Some(w)
215        } else {
216            None
217        }
218    }
219
220    fn as_relation(&self) -> Option<&RcRelation> {
221        if let RcOSMObj::Relation(r) = self {
222            Some(r)
223        } else {
224            None
225        }
226    }
227
228    fn as_node_mut(&mut self) -> Option<&mut RcNode> {
229        if let RcOSMObj::Node(n) = self {
230            Some(n)
231        } else {
232            None
233        }
234    }
235
236    fn as_way_mut(&mut self) -> Option<&mut RcWay> {
237        if let RcOSMObj::Way(w) = self {
238            Some(w)
239        } else {
240            None
241        }
242    }
243
244    fn as_relation_mut(&mut self) -> Option<&mut RcRelation> {
245        if let RcOSMObj::Relation(r) = self {
246            Some(r)
247        } else {
248            None
249        }
250    }
251}
252
253impl OSMObjBase for RcNode {
254    fn id(&self) -> ObjId {
255        self._id
256    }
257    fn version(&self) -> Option<u32> {
258        self._version
259    }
260    fn deleted(&self) -> bool {
261        self._deleted
262    }
263    fn changeset_id(&self) -> Option<u32> {
264        self._changeset_id
265    }
266    fn timestamp(&self) -> &Option<TimestampFormat> {
267        &self._timestamp
268    }
269    fn uid(&self) -> Option<u32> {
270        self._uid
271    }
272    fn user(&self) -> Option<&str> {
273        self._user.as_ref().map(|x| x as _)
274    }
275
276    fn set_id(&mut self, val: impl Into<ObjId>) {
277        self._id = val.into();
278    }
279    fn set_version(&mut self, val: impl Into<Option<u32>>) {
280        self._version = val.into();
281    }
282    fn set_deleted(&mut self, val: bool) {
283        self._deleted = val;
284    }
285    fn set_changeset_id(&mut self, val: impl Into<Option<u32>>) {
286        self._changeset_id = val.into();
287    }
288    fn set_timestamp(&mut self, val: impl Into<Option<TimestampFormat>>) {
289        self._timestamp = val.into();
290    }
291    fn set_uid(&mut self, val: impl Into<Option<u32>>) {
292        self._uid = val.into();
293    }
294    fn set_user<'a>(&mut self, val: impl Into<Option<&'a str>>) {
295        self._user = val.into().map(Rc::from);
296    }
297
298    fn tags<'a>(&'a self) -> Box<dyn ExactSizeIterator<Item = (&'a str, &'a str)> + 'a> {
299        match self._tags {
300            None => Box::new(std::iter::empty()),
301            Some(ref t) => Box::new(t.iter().map(|(k, v)| (k.as_ref(), v.as_ref()))),
302        }
303    }
304
305    fn tag(&self, key: impl AsRef<str>) -> Option<&str> {
306        match &self._tags {
307            None => None,
308            Some(t) => {
309                let key = key.as_ref();
310                t.iter()
311                    .filter_map(|(k, v)| {
312                        if k.as_ref() == key {
313                            Some(v.as_ref())
314                        } else {
315                            None
316                        }
317                    })
318                    .next()
319            }
320        }
321    }
322
323    fn set_tag(&mut self, key: impl AsRef<str>, value: impl Into<String>) {
324        let key = key.as_ref();
325        let value = value.into();
326        match self._tags {
327            None => {
328                self._tags = Some(vec![(Rc::from(key), Rc::from(value.as_str()))]);
329            }
330            Some(ref mut tags) => {
331                let idx = tags
332                    .iter()
333                    .enumerate()
334                    .filter_map(|(i, (k, _))| if k.as_ref() == key { Some(i) } else { None })
335                    .next();
336                match idx {
337                    None => tags.push((Rc::from(key), Rc::from(value.as_str()))),
338                    Some(i) => tags[i] = (key.into(), Rc::from(value.as_str())),
339                }
340            }
341        }
342    }
343
344    fn unset_tag(&mut self, key: impl AsRef<str>) {
345        if let Some(ref mut tags) = self._tags {
346            let key = key.as_ref();
347            let idx = tags
348                .iter()
349                .enumerate()
350                .filter_map(|(i, (k, _))| if k.as_ref() == key { Some(i) } else { None })
351                .next();
352            if let Some(i) = idx {
353                tags.remove(i);
354            }
355        }
356    }
357
358    fn object_type(&self) -> OSMObjectType {
359        OSMObjectType::Node
360    }
361}
362
363impl Node for RcNode {
364    fn lat_lon(&self) -> Option<(Lat, Lon)> {
365        self._lat_lon
366    }
367
368    fn set_lat_lon_direct(&mut self, loc: Option<(Lat, Lon)>) {
369        self._lat_lon = loc;
370    }
371}
372
373impl OSMObjBase for RcWay {
374    fn id(&self) -> ObjId {
375        self._id
376    }
377    fn version(&self) -> Option<u32> {
378        self._version
379    }
380    fn deleted(&self) -> bool {
381        self._deleted
382    }
383    fn changeset_id(&self) -> Option<u32> {
384        self._changeset_id
385    }
386    fn timestamp(&self) -> &Option<TimestampFormat> {
387        &self._timestamp
388    }
389    fn uid(&self) -> Option<u32> {
390        self._uid
391    }
392    fn user(&self) -> Option<&str> {
393        self._user.as_ref().map(|x| x as _)
394    }
395
396    fn set_id(&mut self, val: impl Into<ObjId>) {
397        self._id = val.into();
398    }
399    fn set_version(&mut self, val: impl Into<Option<u32>>) {
400        self._version = val.into();
401    }
402    fn set_deleted(&mut self, val: bool) {
403        self._deleted = val;
404    }
405    fn set_changeset_id(&mut self, val: impl Into<Option<u32>>) {
406        self._changeset_id = val.into();
407    }
408    fn set_timestamp(&mut self, val: impl Into<Option<TimestampFormat>>) {
409        self._timestamp = val.into();
410    }
411    fn set_uid(&mut self, val: impl Into<Option<u32>>) {
412        self._uid = val.into();
413    }
414    fn set_user<'a>(&mut self, val: impl Into<Option<&'a str>>) {
415        self._user = val.into().map(Rc::from);
416    }
417
418    fn tags<'a>(&'a self) -> Box<dyn ExactSizeIterator<Item = (&'a str, &'a str)> + 'a> {
419        Box::new(self._tags.iter().map(|(k, v)| (k.as_ref(), v.as_ref())))
420    }
421
422    fn tag(&self, key: impl AsRef<str>) -> Option<&str> {
423        let key = key.as_ref();
424        self._tags
425            .iter()
426            .filter_map(|(k, v)| {
427                if k.as_ref() == key {
428                    Some(v.as_ref())
429                } else {
430                    None
431                }
432            })
433            .next()
434    }
435
436    fn set_tag(&mut self, key: impl AsRef<str>, value: impl Into<String>) {
437        let key = key.as_ref();
438        let value = value.into();
439        let idx = self
440            ._tags
441            .iter()
442            .enumerate()
443            .filter_map(|(i, (k, _))| if k.as_ref() == key { Some(i) } else { None })
444            .next();
445        match idx {
446            None => self._tags.push((Rc::from(key), Rc::from(value.as_str()))),
447            Some(i) => self._tags[i] = (key.into(), Rc::from(value.as_str())),
448        }
449    }
450
451    fn unset_tag(&mut self, key: impl AsRef<str>) {
452        let key = key.as_ref();
453        let idx = self
454            ._tags
455            .iter()
456            .enumerate()
457            .filter_map(|(i, (k, _))| if k.as_ref() == key { Some(i) } else { None })
458            .next();
459        if let Some(i) = idx {
460            self._tags.remove(i);
461        }
462    }
463
464    fn object_type(&self) -> OSMObjectType {
465        OSMObjectType::Way
466    }
467}
468
469impl Way for RcWay {
470    fn nodes(&self) -> &[ObjId] {
471        &self._nodes
472    }
473
474    fn num_nodes(&self) -> usize {
475        self._nodes.len()
476    }
477
478    fn node(&self, idx: usize) -> Option<ObjId> {
479        self._nodes.get(idx).cloned()
480    }
481    fn set_nodes(&mut self, nodes: impl IntoIterator<Item = impl Into<ObjId>>) {
482        self._nodes.truncate(0);
483        self._nodes.extend(nodes.into_iter().map(|i| i.into()));
484    }
485}
486
487impl OSMObjBase for RcRelation {
488    fn id(&self) -> ObjId {
489        self._id
490    }
491    fn version(&self) -> Option<u32> {
492        self._version
493    }
494    fn deleted(&self) -> bool {
495        self._deleted
496    }
497    fn changeset_id(&self) -> Option<u32> {
498        self._changeset_id
499    }
500    fn timestamp(&self) -> &Option<TimestampFormat> {
501        &self._timestamp
502    }
503    fn uid(&self) -> Option<u32> {
504        self._uid
505    }
506    fn user(&self) -> Option<&str> {
507        self._user.as_ref().map(|x| x as _)
508    }
509
510    fn set_id(&mut self, val: impl Into<ObjId>) {
511        self._id = val.into();
512    }
513    fn set_version(&mut self, val: impl Into<Option<u32>>) {
514        self._version = val.into();
515    }
516    fn set_deleted(&mut self, val: bool) {
517        self._deleted = val;
518    }
519    fn set_changeset_id(&mut self, val: impl Into<Option<u32>>) {
520        self._changeset_id = val.into();
521    }
522    fn set_timestamp(&mut self, val: impl Into<Option<TimestampFormat>>) {
523        self._timestamp = val.into();
524    }
525    fn set_uid(&mut self, val: impl Into<Option<u32>>) {
526        self._uid = val.into();
527    }
528    fn set_user<'a>(&mut self, val: impl Into<Option<&'a str>>) {
529        self._user = val.into().map(Rc::from);
530    }
531
532    fn tags<'a>(&'a self) -> Box<dyn ExactSizeIterator<Item = (&'a str, &'a str)> + 'a> {
533        Box::new(self._tags.iter().map(|(k, v)| (k.as_ref(), v.as_ref())))
534    }
535
536    fn tag(&self, key: impl AsRef<str>) -> Option<&str> {
537        let key = key.as_ref();
538        self._tags
539            .iter()
540            .filter_map(|(k, v)| {
541                if k.as_ref() == key {
542                    Some(v.as_ref())
543                } else {
544                    None
545                }
546            })
547            .next()
548    }
549
550    fn set_tag(&mut self, key: impl AsRef<str>, value: impl Into<String>) {
551        let key = key.as_ref();
552        let value = value.into();
553        let idx = self
554            ._tags
555            .iter()
556            .enumerate()
557            .filter_map(|(i, (k, _))| if k.as_ref() == key { Some(i) } else { None })
558            .next();
559        match idx {
560            None => self._tags.push((Rc::from(key), Rc::from(value.as_str()))),
561            Some(i) => self._tags[i] = (key.into(), Rc::from(value.as_str())),
562        }
563    }
564
565    fn unset_tag(&mut self, key: impl AsRef<str>) {
566        let key = key.as_ref();
567        let idx = self
568            ._tags
569            .iter()
570            .enumerate()
571            .filter_map(|(i, (k, _))| if k.as_ref() == key { Some(i) } else { None })
572            .next();
573        if let Some(i) = idx {
574            self._tags.remove(i);
575        }
576    }
577
578    fn object_type(&self) -> OSMObjectType {
579        OSMObjectType::Relation
580    }
581}
582
583impl Relation for RcRelation {
584    fn members<'a>(
585        &'a self,
586    ) -> Box<dyn ExactSizeIterator<Item = (OSMObjectType, ObjId, &'a str)> + 'a> {
587        Box::new(self._members.iter().map(|(t, o, r)| (*t, *o, r.as_ref())))
588    }
589
590    fn set_members(
591        &mut self,
592        members: impl IntoIterator<Item = (OSMObjectType, ObjId, impl Into<String>)>,
593    ) {
594        self._members.truncate(0);
595
596        self._members.extend(
597            members
598                .into_iter()
599                .map(|(t, i, r)| (t, i, Rc::from(r.into()))),
600        );
601    }
602}