Skip to content

Commit 14a8ce0

Browse files
committed
ns: Rewrite namespace resolution using QName API
1 parent 816b064 commit 14a8ce0

File tree

1 file changed

+30
-30
lines changed

1 file changed

+30
-30
lines changed

src/name.rs

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -284,20 +284,6 @@ impl NamespaceEntry {
284284
Some(Namespace(&buffer[start..start + self.value_len]))
285285
}
286286
}
287-
288-
/// Check if the namespace matches the potentially qualified name
289-
#[inline]
290-
fn is_match(&self, buffer: &[u8], name: QName) -> bool {
291-
match (self.prefix(buffer), name.prefix()) {
292-
// If both parts has no prefixes -> matched
293-
(None, None) => true,
294-
// If one part has prefix but other is not -> not matched
295-
(None, Some(_)) => false,
296-
(Some(_), None) => false,
297-
// Otherwise check that prefixes the same
298-
(Some(definition), Some(usage)) => definition == usage,
299-
}
300-
}
301287
}
302288

303289
/// A namespace management buffer.
@@ -401,20 +387,8 @@ impl NamespaceResolver {
401387
buffer: &'ns [u8],
402388
use_default: bool,
403389
) -> (Option<Namespace<'ns>>, LocalName<'n>) {
404-
let qname = name.into_inner();
405-
self.bindings
406-
.iter()
407-
.rfind(|n| n.is_match(buffer, name))
408-
.map_or((None, LocalName(qname)), |n| {
409-
let len = n.prefix_len;
410-
if len > 0 {
411-
(n.namespace(buffer), LocalName(&qname[len + 1..]))
412-
} else if use_default {
413-
(n.namespace(buffer), LocalName(qname))
414-
} else {
415-
(None, LocalName(qname))
416-
}
417-
})
390+
let (local_name, prefix) = name.decompose();
391+
(self.resolve_prefix(prefix, buffer, use_default), local_name)
418392
}
419393

420394
/// Finds a [namespace name] for a given qualified **element name**, borrow
@@ -433,10 +407,36 @@ impl NamespaceResolver {
433407
/// [unbound]: https://www.w3.org/TR/xml-names11/#scoping
434408
#[inline]
435409
pub fn find<'ns>(&self, element_name: QName, buffer: &'ns [u8]) -> Option<Namespace<'ns>> {
410+
self.resolve_prefix(element_name.prefix(), buffer, true)
411+
}
412+
413+
fn resolve_prefix<'ns>(
414+
&self,
415+
prefix: Option<Prefix>,
416+
buffer: &'ns [u8],
417+
use_default: bool,
418+
) -> Option<Namespace<'ns>> {
436419
self.bindings
437420
.iter()
438-
.rfind(|n| n.is_match(buffer, element_name))
439-
.and_then(|n| n.namespace(buffer))
421+
// Find the last defined binding that corresponds to the given prefix
422+
.rev()
423+
.find_map(|n| match (n.prefix(buffer), prefix) {
424+
// This is default namespace definition and name has no explicit prefix
425+
(None, None) if use_default => Some(n.namespace(buffer)),
426+
(None, None) => Some(None),
427+
428+
// One part has prefix but other is not -> skip
429+
(None, Some(_)) => None,
430+
(Some(_), None) => None,
431+
432+
// Prefixes does not match -> skip
433+
(Some(definition), Some(usage)) if definition != usage => None,
434+
435+
// Prefixes the same, returns corresponding namespace
436+
_ => Some(n.namespace(buffer)),
437+
})
438+
// If no entry found for specified prefix, resolution is unsuccessful
439+
.unwrap_or_default()
440440
}
441441
}
442442

0 commit comments

Comments
 (0)