This commit is contained in:
2026-08-12 14:11:47 -04:00
parent 79894f654d
commit f852da4f4e
48 changed files with 4379 additions and 779 deletions
+63
View File
@@ -0,0 +1,63 @@
use oxigraph::model::TermRef;
use oxilangtag::LanguageTag;
use std::sync::LazyLock;
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<'a>(&self, term: impl Into<TermRef<'a>>) -> bool {
if let TermRef::Literal(literal) = term.into() {
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 primary_language(&self) -> Option<&str> {
match self {
LanguageCondition::ExactMatchOnly(tag) => Some(tag.primary_language()),
LanguageCondition::ExactMatchOrUntagged(tag) => Some(tag.primary_language()),
_ => None,
}
}
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(),
}
}
}