Skip to main content

overpass_lib/query/
union.rs

1use std::{
2    borrow::Cow,
3    collections::{HashSet, hash_set::IntoIter},
4    fmt::Write,
5};
6use crate::{Set, Namer, OverpassQLNamed, OverpassQLError};
7
8/// A [Set] that is composed of all elements found in any member set.
9#[derive(Debug, Clone, Default, PartialEq, Eq)]
10pub struct UnionSet<'a>(
11    /// The collection of sets whose contents make up this set.
12    pub HashSet<Cow<'a, Set<'a>>>,
13);
14
15impl<'a> OverpassQLNamed<'a> for UnionSet<'a> {
16    fn fmt_oql_named<'b, 'c>(&'b self, f: &mut impl Write, namer: &mut Namer<'a, 'c>)
17    -> Result<(), OverpassQLError>
18    where 'b: 'c {
19        write!(f, "(")?;
20        for i in &self.0 {
21            if let Some(n) = namer.get_or_assign(i) {
22                write!(f, ".{n};")?;
23            }
24        }
25        write!(f, ")")?;
26        Ok(())
27    }
28}
29
30impl<'a> UnionSet<'a> {
31    /// An iterator of the sets that must be defined before this set.
32    pub fn dependencies(&self) -> IntoIter<&Set<'a>> {
33        self.0.iter().map(|c| c.as_ref())
34            .collect::<HashSet<_>>().into_iter()
35    }
36}
37
38impl<'a, A> FromIterator<A> for UnionSet<'a>
39where A: Into<Cow<'a, Set<'a>>> {
40    fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
41        Self(iter.into_iter().map(|i| i.into()).collect())
42    }
43}
44
45#[cfg(test)]
46mod test {
47    use super::*;
48    use crate::FilterSet;
49
50    #[test]
51    fn union() {
52        let set = Set::Union(UnionSet(HashSet::from([
53            Cow::Owned(Set::Filter(FilterSet::default())),
54            Cow::Owned(Set::Filter(FilterSet::default())),
55        ])));
56
57        let mut output = String::new();
58        set.fmt_oql_named(&mut output, &mut Namer::new(&set)).unwrap();
59        assert_eq!(output, "(.a;.b;)");
60    }
61}