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