Skip to content

Commit 16168e1

Browse files
committed
ns: Rename namespace resolution functions and document them better
1 parent 0759dfd commit 16168e1

File tree

4 files changed

+163
-28
lines changed

4 files changed

+163
-28
lines changed

Changelog.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@
3434
| |`read_resolved_event` -- borrow from input
3535
| |`read_event_into`
3636
|`read_namespaced_event` |`read_resolved_event_into`
37-
|`event_namespace` |`event_namespace`
38-
|`attribute_namespace` |`attribute_namespace`
37+
| |`resolve`
38+
|`event_namespace` |`resolve_element`
39+
|`attribute_namespace` |`resolve_attribute`
3940

4041

4142
### Bug Fixes

src/name.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,13 +274,13 @@ impl<'a> AsRef<[u8]> for Namespace<'a> {
274274

275275
////////////////////////////////////////////////////////////////////////////////////////////////////
276276

277-
/// Result of [prefix] resolution which creates by [`NsReader::attribute_namespace`],
278-
/// [`NsReader::event_namespace`], [`NsReader::read_resolved_event`] and
277+
/// Result of [prefix] resolution which creates by [`NsReader::resolve_attribute`],
278+
/// [`NsReader::resolve_element`], [`NsReader::read_resolved_event`] and
279279
/// [`NsReader::read_resolved_event_into`] methods.
280280
///
281281
/// [prefix]: Prefix
282-
/// [`NsReader::attribute_namespace`]: crate::reader::NsReader::attribute_namespace
283-
/// [`NsReader::event_namespace`]: crate::reader::NsReader::event_namespace
282+
/// [`NsReader::resolve_attribute`]: crate::reader::NsReader::resolve_attribute
283+
/// [`NsReader::resolve_element`]: crate::reader::NsReader::resolve_element
284284
/// [`NsReader::read_resolved_event`]: crate::reader::NsReader::read_resolved_event
285285
/// [`NsReader::read_resolved_event_into`]: crate::reader::NsReader::read_resolved_event_into
286286
#[derive(Clone, PartialEq, Eq, Hash)]

src/reader/ns_reader.rs

Lines changed: 152 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -96,35 +96,169 @@ impl<R> NsReader<R> {
9696

9797
/// Getters
9898
impl<R> NsReader<R> {
99-
/// Resolves a potentially qualified **event name** into (namespace name, local name).
99+
/// Resolves a potentially qualified **element name** or **attribute name**
100+
/// into (namespace name, local name).
100101
///
101-
/// *Qualified* attribute names have the form `prefix:local-name` where the`prefix` is defined
102-
/// on any containing XML element via `xmlns:prefix="the:namespace:uri"`. The namespace prefix
103-
/// can be defined on the same element as the attribute in question.
102+
/// *Qualified* names have the form `prefix:local-name` where the `prefix`
103+
/// is defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
104+
/// The namespace prefix can be defined on the same element as the name in question.
104105
///
105-
/// *Unqualified* event inherits the current *default namespace*.
106+
/// The method returns following results depending on the `name` shape,
107+
/// `attribute` flag and the presence of the default namespace:
108+
///
109+
/// |attribute|`xmlns="..."`|QName |ResolveResult |LocalName
110+
/// |---------|-------------|-------------------|-----------------------|------------
111+
/// |`true` |Not defined |`local-name` |[`Unbound`] |`local-name`
112+
/// |`true` |Defined |`local-name` |[`Unbound`] |`local-name`
113+
/// |`true` |_any_ |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
114+
/// |`false` |Not defined |`local-name` |[`Unbound`] |`local-name`
115+
/// |`false` |Defined |`local-name` |[`Bound`] (default) |`local-name`
116+
/// |`false` |_any_ |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
117+
///
118+
/// If you want to clearly indicate that name that you resolve is an element
119+
/// or an attribute name, you could use [`resolve_attribute()`] or [`resolve_element()`]
120+
/// methods.
106121
///
107122
/// # Lifetimes
108123
///
109-
/// - `'n`: lifetime of an element name
124+
/// - `'n`: lifetime of a name. Returned local name will be bound to the same
125+
/// lifetime as the name in question.
126+
/// - returned namespace name will be bound to the reader itself
127+
///
128+
/// [`Bound`]: ResolveResult::Bound
129+
/// [`Unbound`]: ResolveResult::Unbound
130+
/// [`Unknown`]: ResolveResult::Unknown
131+
/// [`resolve_attribute()`]: Self::resolve_attribute()
132+
/// [`resolve_element()`]: Self::resolve_element()
110133
#[inline]
111-
pub fn event_namespace<'n>(&self, name: QName<'n>) -> (ResolveResult, LocalName<'n>) {
134+
pub fn resolve<'n>(&self, name: QName<'n>, attribute: bool) -> (ResolveResult, LocalName<'n>) {
135+
self.ns_resolver.resolve(name, &self.buffer, !attribute)
136+
}
137+
138+
/// Resolves a potentially qualified **element name** into (namespace name, local name).
139+
///
140+
/// *Qualified* element names have the form `prefix:local-name` where the
141+
/// `prefix` is defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
142+
/// The namespace prefix can be defined on the same element as the element
143+
/// in question.
144+
///
145+
/// *Unqualified* elements inherits the current *default namespace*.
146+
///
147+
/// The method returns following results depending on the `name` shape and
148+
/// the presence of the default namespace:
149+
///
150+
/// |`xmlns="..."`|QName |ResolveResult |LocalName
151+
/// |-------------|-------------------|-----------------------|------------
152+
/// |Not defined |`local-name` |[`Unbound`] |`local-name`
153+
/// |Defined |`local-name` |[`Bound`] (default) |`local-name`
154+
/// |_any_ |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
155+
///
156+
/// # Lifetimes
157+
///
158+
/// - `'n`: lifetime of an element name. Returned local name will be bound
159+
/// to the same lifetime as the name in question.
160+
/// - returned namespace name will be bound to the reader itself
161+
///
162+
/// # Examples
163+
///
164+
/// This example shows how you can resolve qualified name into a namespace.
165+
/// Note, that in the code like this you do not need to do that manually,
166+
/// because the namespace resolution result returned by the [`read_event()`].
167+
///
168+
/// ```
169+
/// # use pretty_assertions::assert_eq;
170+
/// use quick_xml::events::Event;
171+
/// use quick_xml::name::{Namespace, QName, ResolveResult::*};
172+
/// use quick_xml::NsReader;
173+
///
174+
/// let mut reader = NsReader::from_str("<tag xmlns='root namespace'/>");
175+
///
176+
/// match reader.read_event().unwrap() {
177+
/// Event::Empty(e) => assert_eq!(
178+
/// reader.resolve_element(e.name()),
179+
/// (Bound(Namespace(b"root namespace")), QName(b"tag").into())
180+
/// ),
181+
/// _ => unreachable!(),
182+
/// }
183+
/// ```
184+
///
185+
/// [`Bound`]: ResolveResult::Bound
186+
/// [`Unbound`]: ResolveResult::Unbound
187+
/// [`Unknown`]: ResolveResult::Unknown
188+
/// [`read_event()`]: Self::read_event
189+
#[inline]
190+
pub fn resolve_element<'n>(&self, name: QName<'n>) -> (ResolveResult, LocalName<'n>) {
112191
self.ns_resolver.resolve(name, &self.buffer, true)
113192
}
114193

115194
/// Resolves a potentially qualified **attribute name** into (namespace name, local name).
116195
///
117-
/// *Qualified* attribute names have the form `prefix:local-name` where the`prefix` is defined
118-
/// on any containing XML element via `xmlns:prefix="the:namespace:uri"`. The namespace prefix
119-
/// can be defined on the same element as the attribute in question.
196+
/// *Qualified* attribute names have the form `prefix:local-name` where the
197+
/// `prefix` is defined on any containing XML element via `xmlns:prefix="the:namespace:uri"`.
198+
/// The namespace prefix can be defined on the same element as the attribute
199+
/// in question.
120200
///
121201
/// *Unqualified* attribute names do *not* inherit the current *default namespace*.
122202
///
203+
/// The method returns following results depending on the `name` shape and
204+
/// the presence of the default namespace:
205+
///
206+
/// |`xmlns="..."`|QName |ResolveResult |LocalName
207+
/// |-------------|-------------------|-----------------------|------------
208+
/// |Not defined |`local-name` |[`Unbound`] |`local-name`
209+
/// |Defined |`local-name` |[`Unbound`] |`local-name`
210+
/// |_any_ |`prefix:local-name`|[`Bound`] / [`Unknown`]|`local-name`
211+
///
123212
/// # Lifetimes
124213
///
125-
/// - `'n`: lifetime of an attribute
214+
/// - `'n`: lifetime of an attribute name. Returned local name will be bound
215+
/// to the same lifetime as the name in question.
216+
/// - returned namespace name will be bound to the reader itself
217+
///
218+
/// # Examples
219+
///
220+
/// ```
221+
/// # use pretty_assertions::assert_eq;
222+
/// use quick_xml::events::Event;
223+
/// use quick_xml::events::attributes::Attribute;
224+
/// use quick_xml::name::{Namespace, QName, ResolveResult::*};
225+
/// use quick_xml::NsReader;
226+
///
227+
/// let mut reader = NsReader::from_str("
228+
/// <tag one='1'
229+
/// p:two='2'
230+
/// xmlns='root namespace'
231+
/// xmlns:p='other namespace'/>
232+
/// ");
233+
/// reader.trim_text(true);
234+
///
235+
/// match reader.read_event().unwrap() {
236+
/// Event::Empty(e) => {
237+
/// let mut iter = e.attributes();
238+
///
239+
/// // Unlike elements, attributes without explicit namespace
240+
/// // not bound to any namespace
241+
/// let one = iter.next().unwrap().unwrap();
242+
/// assert_eq!(
243+
/// reader.resolve_attribute(one.key),
244+
/// (Unbound, QName(b"one").into())
245+
/// );
246+
///
247+
/// let two = iter.next().unwrap().unwrap();
248+
/// assert_eq!(
249+
/// reader.resolve_attribute(two.key),
250+
/// (Bound(Namespace(b"other namespace")), QName(b"two").into())
251+
/// );
252+
/// }
253+
/// _ => unreachable!(),
254+
/// }
255+
/// ```
256+
///
257+
/// [`Bound`]: ResolveResult::Bound
258+
/// [`Unbound`]: ResolveResult::Unbound
259+
/// [`Unknown`]: ResolveResult::Unknown
126260
#[inline]
127-
pub fn attribute_namespace<'n>(&self, name: QName<'n>) -> (ResolveResult, LocalName<'n>) {
261+
pub fn resolve_attribute<'n>(&self, name: QName<'n>) -> (ResolveResult, LocalName<'n>) {
128262
self.ns_resolver.resolve(name, &self.buffer, false)
129263
}
130264
}
@@ -133,7 +267,7 @@ impl<R: BufRead> NsReader<R> {
133267
/// Reads the next event into given buffer.
134268
///
135269
/// This method manages namespaces but doesn't resolve them automatically.
136-
/// You should call [`event_namespace()`] if you want to get a namespace.
270+
/// You should call [`resolve_element()`] if you want to get a namespace.
137271
///
138272
/// You also can use [`read_resolved_event_into()`] instead if you want to resolve
139273
/// namespace as soon as you get an event.
@@ -161,7 +295,7 @@ impl<R: BufRead> NsReader<R> {
161295
/// match reader.read_event_into(&mut buf).unwrap() {
162296
/// Event::Start(e) => {
163297
/// count += 1;
164-
/// let (ns, local) = reader.event_namespace(e.name());
298+
/// let (ns, local) = reader.resolve_element(e.name());
165299
/// match local.as_ref() {
166300
/// b"tag1" => assert_eq!(ns, Bound(Namespace(b"www.xxxx"))),
167301
/// b"tag2" => assert_eq!(ns, Bound(Namespace(b"www.yyyy"))),
@@ -180,7 +314,7 @@ impl<R: BufRead> NsReader<R> {
180314
/// assert_eq!(txt, vec!["Test".to_string(), "Test 2".to_string()]);
181315
/// ```
182316
///
183-
/// [`event_namespace()`]: Self::event_namespace
317+
/// [`resolve_element()`]: Self::resolve_element
184318
/// [`read_resolved_event_into()`]: Self::read_resolved_event_into
185319
#[inline]
186320
pub fn read_event_into<'b>(&mut self, buf: &'b mut Vec<u8>) -> Result<Event<'b>> {
@@ -268,7 +402,7 @@ impl<'i> NsReader<&'i [u8]> {
268402
/// Reads the next event, borrow its content from the input buffer.
269403
///
270404
/// This method manages namespaces but doesn't resolve them automatically.
271-
/// You should call [`event_namespace()`] if you want to get a namespace.
405+
/// You should call [`resolve_element()`] if you want to get a namespace.
272406
///
273407
/// You also can use [`read_resolved_event()`] instead if you want to resolve namespace
274408
/// as soon as you get an event.
@@ -295,7 +429,7 @@ impl<'i> NsReader<&'i [u8]> {
295429
/// match reader.read_event().unwrap() {
296430
/// Event::Start(e) => {
297431
/// count += 1;
298-
/// let (ns, local) = reader.event_namespace(e.name());
432+
/// let (ns, local) = reader.resolve_element(e.name());
299433
/// match local.as_ref() {
300434
/// b"tag1" => assert_eq!(ns, Bound(Namespace(b"www.xxxx"))),
301435
/// b"tag2" => assert_eq!(ns, Bound(Namespace(b"www.yyyy"))),
@@ -313,7 +447,7 @@ impl<'i> NsReader<&'i [u8]> {
313447
/// assert_eq!(txt, vec!["Test".to_string(), "Test 2".to_string()]);
314448
/// ```
315449
///
316-
/// [`event_namespace()`]: Self::event_namespace
450+
/// [`resolve_element()`]: Self::resolve_element
317451
/// [`read_resolved_event()`]: Self::read_resolved_event
318452
#[inline]
319453
pub fn read_event(&mut self) -> Result<Event<'i>> {

tests/namespaces.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ fn attributes_empty_ns() {
147147
// we don't care about xmlns attributes for this test
148148
.filter(|kv| kv.key.as_namespace_binding().is_none())
149149
.map(|Attribute { key: name, value }| {
150-
let (opt_ns, local_name) = r.attribute_namespace(name);
150+
let (opt_ns, local_name) = r.resolve_attribute(name);
151151
(opt_ns, local_name.into_inner(), value)
152152
});
153153
assert_eq!(
@@ -186,7 +186,7 @@ fn attributes_empty_ns_expanded() {
186186
// we don't care about xmlns attributes for this test
187187
.filter(|kv| kv.key.as_namespace_binding().is_none())
188188
.map(|Attribute { key: name, value }| {
189-
let (opt_ns, local_name) = r.attribute_namespace(name);
189+
let (opt_ns, local_name) = r.resolve_attribute(name);
190190
(opt_ns, local_name.into_inner(), value)
191191
});
192192
assert_eq!(
@@ -245,7 +245,7 @@ fn default_ns_shadowing_empty() {
245245
// we don't care about xmlns attributes for this test
246246
.filter(|kv| kv.key.as_namespace_binding().is_none())
247247
.map(|Attribute { key: name, value }| {
248-
let (opt_ns, local_name) = r.attribute_namespace(name);
248+
let (opt_ns, local_name) = r.resolve_attribute(name);
249249
(opt_ns, local_name.into_inner(), value)
250250
});
251251
// the attribute should _not_ have a namespace name. The default namespace does not
@@ -301,7 +301,7 @@ fn default_ns_shadowing_expanded() {
301301
// we don't care about xmlns attributes for this test
302302
.filter(|kv| kv.key.as_namespace_binding().is_none())
303303
.map(|Attribute { key: name, value }| {
304-
let (opt_ns, local_name) = r.attribute_namespace(name);
304+
let (opt_ns, local_name) = r.resolve_attribute(name);
305305
(opt_ns, local_name.into_inner(), value)
306306
});
307307
// the attribute should _not_ have a namespace name. The default namespace does not

0 commit comments

Comments
 (0)