46 lines
1.8 KiB
Rust
46 lines
1.8 KiB
Rust
use std::sync::LazyLock;
|
|||
|
|
use oxigraph::model::Term;
|
||
|
|
use oxilangtag::LanguageTag;
|
||
|
|
|
||
|
|
pub const ENGLISH_PRIMARY: &str = "en";
|
||
|
|
|
||
|
|
pub static ENGLISH_OR_UNTAGGED: LazyLock<LanguageCondition> = LazyLock::new(|| {
|
||
|
|
LanguageCondition::ExactMatchOrUntagged(LanguageTag::parse(ENGLISH_PRIMARY.to_string()).unwrap())
|
||
|
|
});
|
||
|
|
|
||
|
|
pub enum LanguageCondition {
|
||
|
|
ExactMatchOnly(LanguageTag<String>),
|
||
|
|
ExactMatchOrUntagged(LanguageTag<String>),
|
||
|
|
UntaggedOnly,
|
||
|
|
AnyOrNone,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl LanguageCondition {
|
||
|
|
pub fn primary_matches_term(&self, term: &Term) -> bool {
|
||
|
|
if let Term::Literal(literal) = term {
|
||
|
|
let tag = literal.language()
|
||
|
|
.map(LanguageTag::parse_and_normalize)
|
||
|
|
.and_then(Result::ok);
|
||
|
|
|
||
|
|
match (tag, self) {
|
||
|
|
(Some(language), LanguageCondition::ExactMatchOnly(expectation)) |
|
||
|
|
(Some(language), LanguageCondition::ExactMatchOrUntagged(expectation)) => language.primary_language() == expectation.primary_language(),
|
||
|
|
(None, LanguageCondition::ExactMatchOrUntagged(_)) => true,
|
||
|
|
(None, LanguageCondition::UntaggedOnly) => true,
|
||
|
|
(_, LanguageCondition::AnyOrNone) => true,
|
||
|
|
_ => false,
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn to_filter_expression(&self, var: &str) -> String {
|
||
|
|
match self {
|
||
|
|
LanguageCondition::ExactMatchOnly(language) => format!(r#"FILTER(langMATCHES(LANG(?{var}), "{language}"))"#),
|
||
|
|
LanguageCondition::ExactMatchOrUntagged(language) => format!(r#"FILTER(langMATCHES(LANG(?{var}), "{language}") || !hasLANG(?{var}))"#),
|
||
|
|
LanguageCondition::UntaggedOnly => format!("FILTER(!hasLANG(?{var}))"),
|
||
|
|
LanguageCondition::AnyOrNone => "".to_string(),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|