use super::types::{NamespaceConstraint, ProcessContents};
pub(crate) fn wildcard_allows_namespace(
constraint: &NamespaceConstraint,
ns: Option<&str>,
) -> bool {
match constraint {
NamespaceConstraint::Any => true,
NamespaceConstraint::Other(target_ns) => {
match ns {
None => false, Some(uri) => match target_ns {
Some(tns) => uri != tns,
None => true,
},
}
}
NamespaceConstraint::Local => ns.is_none(),
NamespaceConstraint::TargetNamespace(target_ns) => ns == target_ns.as_deref(),
NamespaceConstraint::List(uris) => match ns {
None => uris.iter().any(|u| u == "##local"),
Some(uri) => uris.iter().any(|u| u == uri),
},
}
}
pub(super) fn stricter_process_contents(
a: &ProcessContents,
b: &ProcessContents,
) -> ProcessContents {
match (a, b) {
(ProcessContents::Strict, _) | (_, ProcessContents::Strict) => ProcessContents::Strict,
(ProcessContents::Lax, _) | (_, ProcessContents::Lax) => ProcessContents::Lax,
_ => ProcessContents::Skip,
}
}
pub(super) fn intersect_namespace_constraints(
a: &NamespaceConstraint,
b: &NamespaceConstraint,
) -> Option<NamespaceConstraint> {
match (a, b) {
(NamespaceConstraint::Any, other) | (other, NamespaceConstraint::Any) => {
Some(other.clone())
}
(NamespaceConstraint::List(list_a), NamespaceConstraint::List(list_b)) => {
let result: Vec<String> = list_a
.iter()
.filter(|u| list_b.contains(u))
.cloned()
.collect();
if result.is_empty() {
None } else {
Some(NamespaceConstraint::List(result))
}
}
(NamespaceConstraint::Other(tns_a), NamespaceConstraint::Other(_tns_b)) => {
Some(NamespaceConstraint::Other(tns_a.clone()))
}
(NamespaceConstraint::List(list), NamespaceConstraint::Other(tns))
| (NamespaceConstraint::Other(tns), NamespaceConstraint::List(list)) => {
let result: Vec<String> = list
.iter()
.filter(|u| {
if *u == "##local" {
return false; }
match tns {
Some(t) => *u != t,
None => true,
}
})
.cloned()
.collect();
if result.is_empty() {
None
} else {
Some(NamespaceConstraint::List(result))
}
}
(NamespaceConstraint::Local, NamespaceConstraint::Local) => {
Some(NamespaceConstraint::Local)
}
(NamespaceConstraint::Local, NamespaceConstraint::Other(_))
| (NamespaceConstraint::Other(_), NamespaceConstraint::Local) => None,
(NamespaceConstraint::Local, NamespaceConstraint::TargetNamespace(_))
| (NamespaceConstraint::TargetNamespace(_), NamespaceConstraint::Local) => None,
(NamespaceConstraint::Local, NamespaceConstraint::List(list))
| (NamespaceConstraint::List(list), NamespaceConstraint::Local) => {
if list.iter().any(|u| u == "##local") {
Some(NamespaceConstraint::Local)
} else {
None
}
}
(NamespaceConstraint::TargetNamespace(a_tns), NamespaceConstraint::TargetNamespace(_)) => {
Some(NamespaceConstraint::TargetNamespace(a_tns.clone()))
}
(NamespaceConstraint::TargetNamespace(_), NamespaceConstraint::Other(_))
| (NamespaceConstraint::Other(_), NamespaceConstraint::TargetNamespace(_)) => None,
(NamespaceConstraint::TargetNamespace(tns), NamespaceConstraint::List(list))
| (NamespaceConstraint::List(list), NamespaceConstraint::TargetNamespace(tns)) => match tns
{
Some(t) if list.contains(t) => Some(NamespaceConstraint::TargetNamespace(tns.clone())),
_ => None,
},
}
}
pub(super) fn union_namespace_constraints(
a: &NamespaceConstraint,
b: &NamespaceConstraint,
) -> NamespaceConstraint {
match (a, b) {
(NamespaceConstraint::Any, _) | (_, NamespaceConstraint::Any) => NamespaceConstraint::Any,
(NamespaceConstraint::List(list_a), NamespaceConstraint::List(list_b)) => {
let mut result = list_a.clone();
for u in list_b {
if !result.contains(u) {
result.push(u.clone());
}
}
NamespaceConstraint::List(result)
}
_ => NamespaceConstraint::Any,
}
}