Skip to main content

overpass_lib/builder/
filter.rs

1use std::borrow::Cow;
2use crate::{Bbox, FilterSet, FilterType, RecurseFilter, SaniStr, Set, SetBuilder, TagFilter, Builder};
3#[cfg(doc)]
4use crate::{Node, Way, Relation};
5
6/// A convenient builder API for [FilterSet].
7pub struct FilterSetBuilder<'a>(
8    /// The set being configured.
9    pub FilterSet<'a>,
10);
11
12impl<'a> Builder<'a> for FilterSetBuilder<'a> {}
13
14impl<'a> Into<Set<'a>> for FilterSetBuilder<'a> {
15    fn into(self) -> Set<'a> {
16        self.0.into()
17    }
18}
19
20impl<'a> Into<Cow<'a, Set<'a>>> for FilterSetBuilder<'a> {
21    fn into(self) -> Cow<'a, Set<'a>> {
22        Cow::Owned(self.into())
23    }
24}
25
26impl<'a> IntoIterator for FilterSetBuilder<'a> {
27    type Item = FilterSetBuilder<'a>;
28    type IntoIter = std::array::IntoIter<Self::Item, 1>;
29    fn into_iter(self) -> Self::IntoIter {
30        [self].into_iter()
31    }
32}
33
34/// Methods to create new [FilterSet]s.
35impl SetBuilder {
36    /// Start a new filter set containing [Node]s, i.e. [FilterType::Node].
37    pub fn all_nodes<'a>() -> FilterSetBuilder<'a> {
38        FilterSetBuilder(FilterSet {
39            filter_type: FilterType::Node,
40            ..Default::default()
41        })
42    }
43
44    /// Start a new filter set containing the [Node]s common to all provided sets. See [FilterSet::inputs].
45    pub fn nodes_from<'a, T>(sets: impl IntoIterator<Item=T>)
46    -> FilterSetBuilder<'a>
47    where T: Into<Cow<'a, Set<'a>>> {
48        FilterSetBuilder(FilterSet {
49            filter_type: FilterType::Node,
50            inputs: sets.into_iter().map(|i| i.into()).collect(),
51            ..Default::default()
52        })
53    }
54
55    /// Start a new filter set containing [Way]s, i.e. [FilterType::Way].
56    pub fn all_ways<'a>() -> FilterSetBuilder<'a> {
57        FilterSetBuilder(FilterSet {
58            filter_type: FilterType::Way,
59            ..Default::default()
60        })
61    }
62
63    /// Start a new filter set containing the [Way]s common to all provided sets. See [FilterSet::inputs].
64    pub fn ways_from<'a, T>(sets: impl IntoIterator<Item=T>)
65    -> FilterSetBuilder<'a>
66    where T: Into<Cow<'a, Set<'a>>> {
67        FilterSetBuilder(FilterSet {
68            filter_type: FilterType::Way,
69            inputs: sets.into_iter().map(|i| i.into()).collect(),
70            ..Default::default()
71        })
72    }
73    
74    /// Start a new filter set containing [Relation]s, i.e. [FilterType::Relation].
75    pub fn all_relations<'a>() -> FilterSetBuilder<'a> {
76        FilterSetBuilder(FilterSet {
77            filter_type: FilterType::Relation,
78            ..Default::default()
79        })
80    }
81
82    /// Start a new filter set containing the [Relation]s common to all provided sets. See [FilterSet::inputs].
83    pub fn relations_from<'a, T>(sets: impl IntoIterator<Item=T>)
84    -> FilterSetBuilder<'a>
85    where T: Into<Cow<'a, Set<'a>>> {
86        FilterSetBuilder(FilterSet {
87            filter_type: FilterType::Relation,
88            inputs: sets.into_iter().map(|i| i.into()).collect(),
89            ..Default::default()
90        })
91    }
92    
93    /// Start a new filter set containing any element type, i.e. [FilterType::Any].
94    pub fn any_type<'a>() -> FilterSetBuilder<'a> {
95        FilterSetBuilder(FilterSet {
96            filter_type: FilterType::Any,
97            ..Default::default()
98        })
99    }
100
101    /// Start a new filter set containing the elements common to all provided sets. See [FilterSet::inputs].
102    pub fn any_from<'a, T>(sets: impl IntoIterator<Item=T>)
103    -> FilterSetBuilder<'a>
104    where T: Into<Cow<'a, Set<'a>>> {
105        FilterSetBuilder(FilterSet {
106            filter_type: FilterType::Any,
107            inputs: sets.into_iter().map(|i| i.into()).collect(),
108            ..Default::default()
109        })
110    }
111    
112    /// Start a new filter set containing [Node]s or [Way]s, i.e. [FilterType::NodeOrWay].
113    pub fn all_nodes_or_ways<'a>() -> FilterSetBuilder<'a> {
114        FilterSetBuilder(FilterSet {
115            filter_type: FilterType::NodeOrWay,
116            ..Default::default()
117        })
118    }
119
120    /// Start a new filter set containing [Node]s and [Way]s common to all provided sets. See [FilterSet::inputs].
121    pub fn nodes_or_ways_from<'a, T>(sets: impl IntoIterator<Item=T>)
122    -> FilterSetBuilder<'a>
123    where T: Into<Cow<'a, Set<'a>>> {
124        FilterSetBuilder(FilterSet {
125            filter_type: FilterType::NodeOrWay,
126            inputs: sets.into_iter().map(|i| i.into()).collect(),
127            ..Default::default()
128        })
129    }
130    
131    /// Start a new filter set containing [Node]s or [Relation]s, i.e. [FilterType::NodeOrRelation].
132    pub fn all_nodes_or_relations<'a>() -> FilterSetBuilder<'a> {
133        FilterSetBuilder(FilterSet {
134            filter_type: FilterType::NodeOrRelation,
135            ..Default::default()
136        })
137    }
138
139    /// Start a new filter set containing the [Node]s and [Relation]s common to all provided sets. See [FilterSet::inputs].
140    pub fn nodes_or_relations_from<'a, T>(sets: impl IntoIterator<Item=T>)
141    -> FilterSetBuilder<'a>
142    where T: Into<Cow<'a, Set<'a>>> {
143        FilterSetBuilder(FilterSet {
144            filter_type: FilterType::NodeOrRelation,
145            inputs: sets.into_iter().map(|i| i.into()).collect(),
146            ..Default::default()
147        })
148    }
149    
150    /// Start a new filter set containing [Way]s or [Relation]s, i.e. [FilterType::WayOrRelation].
151    pub fn all_ways_or_relations<'a>() -> FilterSetBuilder<'a> {
152        FilterSetBuilder(FilterSet {
153            filter_type: FilterType::WayOrRelation,
154            ..Default::default()
155        })
156    }
157
158    /// Start a new filter set containing the [Way]s and [Relation]s common to all provided sets. See [FilterSet::inputs].
159    pub fn ways_or_relations_from<'a, T>(sets: impl IntoIterator<Item=T>)
160    -> FilterSetBuilder<'a>
161    where T: Into<Cow<'a, Set<'a>>> {
162        FilterSetBuilder(FilterSet {
163            filter_type: FilterType::WayOrRelation,
164            inputs: sets.into_iter().map(|i| i.into()).collect(),
165            ..Default::default()
166        })
167    }
168    /*
169    pub fn all_derived<'a>() -> FilterSetBuilder<'a> {
170        FilterSetBuilder(FilterSet {
171            filter_type: FilterType::Derived,
172            ..Default::default()
173        })
174    }
175
176    pub fn derived_from<'a, T>(sets: impl IntoIterator<Item=T>)
177    -> FilterSetBuilder<'a>
178    where T: Into<Cow<'a, Set<'a>>> {
179        FilterSetBuilder(FilterSet {
180            filter_type: FilterType::Derived,
181            inputs: sets.into_iter().map(|i| i.into()).collect(),
182            ..Default::default()
183        })
184    }
185    */
186    /// Start a new filter set containing elements identified as areas, i.e. [FilterType::Area].
187    pub fn all_areas<'a>() -> FilterSetBuilder<'a> {
188        FilterSetBuilder(FilterSet {
189            filter_type: FilterType::Area,
190            ..Default::default()
191        })
192    }
193
194    /// Start a new filter set containing the [Area](FilterType::Area) elements common to all provided sets. See [FilterSet::inputs].
195    pub fn areas_from<'a, T>(sets: impl IntoIterator<Item=T>)
196    -> FilterSetBuilder<'a>
197    where T: Into<Cow<'a, Set<'a>>> {
198        FilterSetBuilder(FilterSet {
199            filter_type: FilterType::Area,
200            inputs: sets.into_iter().map(|i| i.into()).collect(),
201            ..Default::default()
202        })
203    }
204}
205
206impl<'a> FilterSetBuilder<'a> {
207    /// Restrict this set to only elements with the given identifier. See [FilterSet::id_filters].
208    pub fn with_id(mut self, id: i64) -> Self {
209        self.0.id_filters.clear();
210        self.0.id_filters.insert(id);
211        self
212    }
213
214    /// Restrict this set to only elements with the given identifiers. See [FilterSet::id_filters].
215    pub fn with_ids(mut self, ids: impl IntoIterator<Item=i64>) -> Self {
216        self.0.id_filters.clear();
217        for id in ids {
218            self.0.id_filters.insert(id);
219        }
220        self
221    }
222
223    /// Restrict this set to only elements contained by the given bounding box. See [FilterSet::bbox_filter].
224    pub fn within_bounds(mut self, bbox: impl Into<Bbox>) -> Self {
225        self.0.bbox_filter = Some(bbox.into());
226        self
227    }
228
229    /// Restrict this set to only elements that have a tag of the given name. See [TagFilter::Exists].
230    pub fn with_tag(mut self, tag: &'a str) -> Self {
231        self.0.tag_filters.insert(TagFilter::exists(tag));
232        self
233    }
234
235    /// Restrict this set to only elements that do not have a tag of the given name. See [TagFilter::NotExists].
236    pub fn without_tag(mut self, tag: &'a str) -> Self {
237        self.0.tag_filters.insert(TagFilter::not_exists(tag));
238        self
239    }
240
241    /// Restrict this set to only elements that have the given tag with the given value. See [TagFilter::Equals].
242    pub fn with_tag_value(mut self, tag: &'a str, value: &'a str) -> Self {
243        self.0.tag_filters.insert(TagFilter::equals(tag, value));
244        self
245    }
246
247    /// Restrict this set to only elements that do not have the given tag, or have a value different from the given value.
248    /// See [TagFilter::NotEquals].
249    pub fn without_tag_value(mut self, tag: &'a str, value: &'a str) -> Self {
250        self.0.tag_filters.insert(TagFilter::not_equals(tag, value));
251        self
252    }
253
254    /// Restrict this set to only elements that have the given tag with a value that matches the given regular expression.
255    /// See [TagFilter::Matches].
256    pub fn with_tag_value_matching(mut self, tag: &'a str, value_pat: &'a str) -> Self {
257        self.0.tag_filters.insert(TagFilter::matches(tag, value_pat));
258        self
259    }
260
261    /// Restrict this set to only elements that do not have the given tag, or have a value that does not match the given
262    /// regular expression.
263    /// See [TagFilter::NotMatches].
264    pub fn without_tag_value_matching(mut self, tag: &'a str, value_pat: &'a str) -> Self {
265        self.0.tag_filters.insert(TagFilter::not_matches(tag, value_pat));
266        self
267    }
268
269    /// Restrict this set to only elements that have a tag matching the given regular expression,
270    /// with a value that matches the given regular expression.
271    /// See [TagFilter::NameValueMatches].
272    pub fn with_tag_name_and_value_matching(mut self, tag_pat: &'a str, value_pat: &'a str) -> Self {
273        self.0.tag_filters.insert(TagFilter::name_value_matches(tag_pat, value_pat));
274        self
275    }
276
277    /// Restrict this set to only elements that have tags of the given names. See [TagFilter::Exists].
278    pub fn with_tags(mut self, tags: impl IntoIterator<Item=&'a str>) -> Self {
279        for i in tags {
280            self.0.tag_filters.insert(TagFilter::Exists(SaniStr(i)));
281        }
282        self
283    }
284
285    /// Restrict this set to only elements that do not have tags of the given names. See [TagFilter::NotExists].
286    pub fn without_tags(mut self, tags: impl IntoIterator<Item=&'a str>) -> Self {
287        for i in tags {
288            self.0.tag_filters.insert(TagFilter::NotExists(SaniStr(i)));
289        }
290        self
291    }
292
293    /// Restrict this set to only elements that have the given tags with the given values. See [TagFilter::Equals].
294    pub fn with_tag_values(
295        mut self, 
296        tags: impl IntoIterator<Item=(&'a str, &'a str)>,
297    ) -> Self {
298        for (n, v) in tags {
299            self.0.tag_filters.insert(TagFilter::Equals(SaniStr(n), SaniStr(v)));
300        }
301        self
302    }
303
304    /// Restrict this set to only elements that do not have the given tags, or have values different from the given values.
305    /// See [TagFilter::NotEquals].
306    pub fn without_tag_values(
307        mut self, 
308        tags: impl IntoIterator<Item=(&'a str, &'a str)>,
309    ) -> Self {
310        for (n, v) in tags {
311            self.0.tag_filters.insert(TagFilter::NotEquals(SaniStr(n), SaniStr(v)));
312        }
313        self
314    }
315
316    /// Restrict this set to only elements that have the given tags with values that matches the given regular expressions.
317    /// See [TagFilter::Matches].
318    pub fn with_tag_values_matching(
319        mut self, 
320        tags: impl IntoIterator<Item=(&'a str, &'a str)>,
321    ) -> Self {
322        for (n, v) in tags {
323            self.0.tag_filters.insert(TagFilter::Matches(SaniStr(n), SaniStr(v)));
324        }
325        self
326    }
327
328    /// Restrict this set to only elements that do not have the given tags, or have values that does not match the given
329    /// regular expressions.
330    /// See [TagFilter::NotMatches].
331    pub fn without_tag_values_matching(
332        mut self, 
333        tags: impl IntoIterator<Item=(&'a str, &'a str)>,
334    ) -> Self {
335        for (n, v) in tags {
336            self.0.tag_filters.insert(TagFilter::NotMatches(SaniStr(n), SaniStr(v)));
337        }
338        self
339    }
340
341    /// Restrict this set to only elements that have tags matching the given regular expressions,
342    /// with values that matches the given regular expressions.
343    /// See [TagFilter::NameValueMatches].
344    pub fn with_tag_names_and_values_matching(
345        mut self, 
346        tags: impl IntoIterator<Item=(&'a str, &'a str)>,
347    ) -> Self {
348        for (n, v) in tags {
349            self.0.tag_filters.insert(TagFilter::NameValueMatches(SaniStr(n), SaniStr(v)));
350        }
351        self
352    }
353
354    /// Restrict this set to only [Node]s that are members of a [Way] in the given set.
355    /// See [RecurseFilter::WithinWays].
356    pub fn within_ways(mut self, set: impl Into<Cow<'a, Set<'a>>>) -> Self {
357        self.0.recurse_filters.insert(RecurseFilter::WithinWays { input: set.into() });
358        self
359    }
360
361    /// Restrict this set to only elements that are members of a [Relation] in the given set.
362    /// See [RecurseFilter::WithinRelations].
363    pub fn within_relations(mut self, set: impl Into<Cow<'a, Set<'a>>>) -> Self {
364        self.0.recurse_filters.insert(RecurseFilter::WithinRelations { input: set.into(), role: None });
365        self
366    }
367
368    /// Restrict this set to only elements that are members of a [Relation] in the given set, and that membership has
369    /// the given role.
370    /// See [RecurseFilter::WithinRelations].
371    pub fn within_relations_with_role(
372        mut self, 
373        role: &'a str, 
374        set: impl Into<Cow<'a, Set<'a>>>,
375    ) -> Self {
376        self.0.recurse_filters.insert(RecurseFilter::WithinRelations { input: set.into(), role: Some(SaniStr(role)) });
377        self
378    }
379
380    /// Restrict this set to only elements that have a [Node] in this set as a member.
381    /// See [RecurseFilter::ContainingNodes].
382    pub fn containing_nodes(mut self, set: impl Into<Cow<'a, Set<'a>>>) -> Self {
383        self.0.recurse_filters.insert(RecurseFilter::ContainingNodes { input: set.into(), role: None });
384        self
385    }
386
387    /// Restrict this set to only elements that have a [Node] in this set as a member, and that
388    /// membership has the given role.
389    /// See [RecurseFilter::ContainingNodes].
390    pub fn containing_nodes_with_role(
391        mut self, 
392        role: &'a str, 
393        set: impl Into<Cow<'a, Set<'a>>>,
394    ) -> Self {
395        self.0.recurse_filters.insert(RecurseFilter::ContainingNodes { input: set.into(), role: Some(SaniStr(role)) });
396        self
397    }
398
399    /// Restrict this set to only elements that have a [Way] in this set as a member.
400    /// See [RecurseFilter::ContainingWays].
401    pub fn containing_ways(mut self, set: impl Into<Cow<'a, Set<'a>>>) -> Self {
402        self.0.recurse_filters.insert(RecurseFilter::ContainingWays { input: set.into(), role: None });
403        self
404    }
405
406    /// Restrict this set to only elements that have a [Way] in this set as a member, and that
407    /// membership has the given role.
408    /// See [RecurseFilter::ContainingWays].
409    pub fn containing_ways_with_role(
410        mut self, 
411        role: &'a str, 
412        set: impl Into<Cow<'a, Set<'a>>>,
413    ) -> Self {
414        self.0.recurse_filters.insert(RecurseFilter::ContainingWays { input: set.into(), role: Some(SaniStr(role)) });
415        self
416    }
417
418    /// Restrict this set to only elements that have a [Relation] in this set as a member.
419    /// See [RecurseFilter::ContainingRelations].
420    pub fn containing_relations(mut self, set: impl Into<Cow<'a, Set<'a>>>) -> Self {
421        self.0.recurse_filters.insert(RecurseFilter::ContainingRelations { input: set.into(), role: None });
422        self
423    }
424
425    /// Restrict this set to only elements that have a [Relation] in this set as a member, and that
426    /// membership has the given role.
427    /// See [RecurseFilter::ContainingRelations].
428    pub fn containing_relations_with_role(
429        mut self, 
430        role: &'a str, 
431        set: impl Into<Cow<'a, Set<'a>>>,
432    ) -> Self {
433        self.0.recurse_filters.insert(RecurseFilter::ContainingRelations { input: set.into(), role: Some(SaniStr(role)) });
434        self
435    }
436}
437
438#[cfg(test)]
439mod test {
440    use super::*;
441
442    fn _all_nodes_from() {
443        let _ = SetBuilder::nodes_from(SetBuilder::all_nodes());
444
445        let set: Set = SetBuilder::all_ways().into();
446        let _ = SetBuilder::nodes_from([&set]);
447    }
448}