mwtitle/
interwiki_set.rs

1/*
2Copyright (C) 2021 Erutuon
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 3 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18use std::collections::HashSet;
19
20use crate::{
21    namespace_map::{NamespaceString, NamespaceStringBorrowed},
22    site_info::Interwiki,
23};
24
25/// A case-insensitive set for interwikis.
26#[derive(Clone, Debug, PartialEq, Eq)]
27pub struct InterwikiSet(HashSet<NamespaceString>);
28
29impl InterwikiSet {
30    /// Given an iterator of `Interwiki`s, returns an `InterwikiSet`
31    /// of all interwikis, and an `InterwikiSet` of local interwikis
32    /// (where `local_interwiki == true`).
33    pub fn all_and_local_from_iter<I: IntoIterator<Item = Interwiki>>(
34        iter: I,
35    ) -> (Self, Self) {
36        let mut all = Self(HashSet::new());
37        let mut local = Self(HashSet::new());
38        for interwiki in iter {
39            let string = NamespaceString(interwiki.prefix);
40            if interwiki.local_interwiki {
41                local.0.insert(string.clone());
42            }
43            all.0.insert(string);
44        }
45        (all, local)
46    }
47
48    /// Equivalent of `InterwikiLookup::isValidInterwiki()`.
49    pub fn contains(&self, interwiki: &str) -> bool {
50        self.0
51            .contains(NamespaceStringBorrowed::from_str(interwiki))
52    }
53}
54
55/// This implementation makes it possible to construct an `InterwikiSet`
56/// even though its item type `NamespaceMap` is private.
57impl FromIterator<String> for InterwikiSet {
58    fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
59        Self(iter.into_iter().map(NamespaceString).collect())
60    }
61}
62
63#[test]
64fn lookup_is_case_insensitive() {
65    let (set, local) = InterwikiSet::all_and_local_from_iter(
66        ["w", "wikt"].into_iter().map(|prefix| Interwiki {
67            prefix: prefix.into(),
68            local_interwiki: prefix == "w",
69        }),
70    );
71    assert!(set.contains("w"));
72    assert!(set.contains("W"));
73    assert!(set.contains("wikt"));
74    assert!(set.contains("WIKT"));
75    assert!(set.contains("WiKt"));
76    assert!(local.contains("w"));
77    assert!(!local.contains("wikt"));
78}