Skip to content

Commit ae2219f

Browse files
committed
ns: Change BytesStart::name() and BytesEnd::name() to return QName
and `BytesStart::local_name()` and `BytesEnd::local_name()` to return `LocalName`
1 parent 2a83743 commit ae2219f

17 files changed

+105
-98
lines changed

Changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
and returns `ResolveResult` and `LocalName`, `read_event_namespaced` now
5353
returns `ResolveResult` instead of `Option<[u8]>`
5454
- [#393]: Types of `Attribute::key` and `Attr::key()` changed to `QName`
55+
- [#393]: Now `BytesStart::name()` and `BytesEnd::name()` returns `QName`, and
56+
`BytesStart::local_name()` and `BytesEnd::local_name()` returns `LocalName`
5557

5658
### New Tests
5759

examples/custom_entities.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
3737
custom_entities.insert(cap[1].to_vec(), cap[2].to_vec());
3838
}
3939
}
40-
Ok(Event::Start(ref e)) => match e.name() {
40+
Ok(Event::Start(ref e)) => match e.name().as_ref() {
4141
b"test" => println!(
4242
"attributes values: {:?}",
4343
e.attributes()

examples/issue68.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,11 @@ fn parse_report(xml_data: &str) -> Vec<Resource> {
8383

8484
loop {
8585
match reader.read_namespaced_event(&mut buf, &mut ns_buffer) {
86-
Ok((namespace_value, Event::Start(e))) => {
87-
let namespace_value = Option::<Namespace>::try_from(namespace_value)
86+
Ok((ns, Event::Start(e))) => {
87+
let ns = Option::<Namespace>::try_from(ns)
8888
.unwrap_or_default() // Treat unknown prefixes as not bound to any namespace
8989
.unwrap_or(Namespace(b""));
90-
match (depth, state, namespace_value.as_ref(), e.local_name()) {
90+
match (depth, state, ns.as_ref(), e.local_name().as_ref()) {
9191
(0, State::Root, b"DAV:", b"multistatus") => state = State::MultiStatus,
9292
(1, State::MultiStatus, b"DAV:", b"response") => {
9393
state = State::Response;
@@ -100,12 +100,11 @@ fn parse_report(xml_data: &str) -> Vec<Resource> {
100100
}
101101
depth += 1;
102102
}
103-
Ok((namespace_value, Event::End(e))) => {
104-
let namespace_value = Option::<Namespace>::try_from(namespace_value)
103+
Ok((ns, Event::End(e))) => {
104+
let ns = Option::<Namespace>::try_from(ns)
105105
.unwrap_or_default() // Treat unknown prefixes as not bound to any namespace
106106
.unwrap_or(Namespace(b""));
107-
let local_name = e.local_name();
108-
match (depth, state, namespace_value.as_ref(), local_name) {
107+
match (depth, state, ns.as_ref(), e.local_name().as_ref()) {
109108
(1, State::MultiStatus, b"DAV:", b"multistatus") => state = State::Root,
110109
(2, State::MultiStatus, b"DAV:", b"multistatus") => state = State::MultiStatus,
111110
_ => {}

examples/nested_readers.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn main() -> Result<(), quick_xml::Error> {
2121
let mut found_tables = Vec::new();
2222
loop {
2323
match reader.read_event(&mut buf)? {
24-
Event::Start(element) => match element.name() {
24+
Event::Start(element) => match element.name().as_ref() {
2525
b"w:tbl" => {
2626
count += 1;
2727
let mut stats = TableStat {
@@ -34,19 +34,21 @@ fn main() -> Result<(), quick_xml::Error> {
3434
loop {
3535
skip_buf.clear();
3636
match reader.read_event(&mut skip_buf)? {
37-
Event::Start(element) => match element.name() {
37+
Event::Start(element) => match element.name().as_ref() {
3838
b"w:tr" => {
3939
stats.rows.push(vec![]);
4040
row_index = stats.rows.len() - 1;
4141
}
4242
b"w:tc" => {
43-
stats.rows[row_index]
44-
.push(String::from_utf8(element.name().to_vec()).unwrap());
43+
stats.rows[row_index].push(
44+
String::from_utf8(element.name().as_ref().to_vec())
45+
.unwrap(),
46+
);
4547
}
4648
_ => {}
4749
},
4850
Event::End(element) => {
49-
if element.name() == b"w:tbl" {
51+
if element.name().as_ref() == b"w:tbl" {
5052
found_tables.push(stats);
5153
break;
5254
}

examples/read_texts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ fn main() {
1313

1414
loop {
1515
match reader.read_event(&mut buf) {
16-
Ok(Event::Start(ref e)) if e.name() == b"tag2" => {
16+
Ok(Event::Start(ref e)) if e.name().as_ref() == b"tag2" => {
1717
txt.push(
1818
reader
1919
.read_text(b"tag2", &mut Vec::new())

src/de/map.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ where
275275
let key = if let Some(p) = self
276276
.unflatten_fields
277277
.iter()
278-
.position(|f| e.name() == &f[UNFLATTEN_PREFIX.len()..])
278+
.position(|f| e.name().as_ref() == &f[UNFLATTEN_PREFIX.len()..])
279279
{
280280
// Used to deserialize elements, like:
281281
// <root>
@@ -290,7 +290,7 @@ where
290290
// }
291291
seed.deserialize(self.unflatten_fields.remove(p).into_deserializer())
292292
} else {
293-
let name = Cow::Borrowed(e.local_name());
293+
let name = Cow::Borrowed(e.local_name().into_inner());
294294
seed.deserialize(EscapedDeserializer::new(name, decoder, false))
295295
};
296296
key.map(Some)
@@ -606,7 +606,7 @@ where
606606
// Stop iteration after reaching a closing tag
607607
DeEvent::End(e) if e.name() == self.map.start.name() => Ok(None),
608608
// This is a unmatched closing tag, so the XML is invalid
609-
DeEvent::End(e) => Err(DeError::UnexpectedEnd(e.name().to_owned())),
609+
DeEvent::End(e) => Err(DeError::UnexpectedEnd(e.name().as_ref().to_owned())),
610610
// We cannot get `Eof` legally, because we always inside of the
611611
// opened tag `self.map.start`
612612
DeEvent::Eof => Err(DeError::UnexpectedEof),

src/de/mod.rs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -514,16 +514,16 @@ where
514514
match self.write.back() {
515515
// Skip all subtree, if we skip a start event
516516
Some(DeEvent::Start(e)) => {
517-
let end = e.name().to_owned();
517+
let end = e.name().as_ref().to_owned();
518518
let mut depth = 0;
519519
loop {
520520
let event = self.next()?;
521521
match event {
522-
DeEvent::Start(ref e) if e.name() == end => {
522+
DeEvent::Start(ref e) if e.name().as_ref() == end => {
523523
self.skip_event(event)?;
524524
depth += 1;
525525
}
526-
DeEvent::End(ref e) if e.name() == end => {
526+
DeEvent::End(ref e) if e.name().as_ref() == end => {
527527
self.skip_event(event)?;
528528
if depth == 0 {
529529
return Ok(());
@@ -571,7 +571,9 @@ where
571571
let e = self.next()?;
572572
match e {
573573
DeEvent::Start(e) => return Ok(Some(e)),
574-
DeEvent::End(e) => return Err(DeError::UnexpectedEnd(e.name().to_owned())),
574+
DeEvent::End(e) => {
575+
return Err(DeError::UnexpectedEnd(e.name().as_ref().to_owned()))
576+
}
575577
DeEvent::Eof => return Ok(None),
576578
_ => (), // ignore texts
577579
}
@@ -631,20 +633,24 @@ where
631633
DeEvent::Text(t) if unescape => t.unescape()?,
632634
DeEvent::Text(t) => BytesCData::new(t.into_inner()),
633635
DeEvent::CData(t) => t,
634-
DeEvent::Start(s) => return Err(DeError::UnexpectedStart(s.name().to_owned())),
636+
DeEvent::Start(s) => {
637+
return Err(DeError::UnexpectedStart(s.name().as_ref().to_owned()))
638+
}
635639
// We can get End event in case of `<tag></tag>` or `<tag/>` input
636640
// Return empty text in that case
637641
DeEvent::End(end) if end.name() == e.name() => {
638642
return Ok(BytesCData::new(&[] as &[u8]));
639643
}
640-
DeEvent::End(end) => return Err(DeError::UnexpectedEnd(end.name().to_owned())),
644+
DeEvent::End(end) => {
645+
return Err(DeError::UnexpectedEnd(end.name().as_ref().to_owned()))
646+
}
641647
DeEvent::Eof => return Err(DeError::UnexpectedEof),
642648
};
643-
self.read_to_end(e.name())?;
649+
self.read_to_end(e.name().as_ref())?;
644650
Ok(t)
645651
}
646-
DeEvent::Start(e) => Err(DeError::UnexpectedStart(e.name().to_owned())),
647-
DeEvent::End(e) => Err(DeError::UnexpectedEnd(e.name().to_owned())),
652+
DeEvent::Start(e) => Err(DeError::UnexpectedStart(e.name().as_ref().to_owned())),
653+
DeEvent::End(e) => Err(DeError::UnexpectedEnd(e.name().as_ref().to_owned())),
648654
DeEvent::Eof => Err(DeError::UnexpectedEof),
649655
}
650656
}
@@ -662,10 +668,10 @@ where
662668
let mut depth = 0;
663669
loop {
664670
match self.read.pop_front() {
665-
Some(DeEvent::Start(e)) if e.name() == name => {
671+
Some(DeEvent::Start(e)) if e.name().as_ref() == name => {
666672
depth += 1;
667673
}
668-
Some(DeEvent::End(e)) if e.name() == name => {
674+
Some(DeEvent::End(e)) if e.name().as_ref() == name => {
669675
if depth == 0 {
670676
return Ok(());
671677
}
@@ -685,8 +691,8 @@ where
685691
fn read_to_end(&mut self, name: &[u8]) -> Result<(), DeError> {
686692
// First one might be in self.peek
687693
match self.next()? {
688-
DeEvent::Start(e) => self.reader.read_to_end(e.name())?,
689-
DeEvent::End(e) if e.name() == name => return Ok(()),
694+
DeEvent::Start(e) => self.reader.read_to_end(e.name().as_ref())?,
695+
DeEvent::End(e) if e.name().as_ref() == name => return Ok(()),
690696
_ => (),
691697
}
692698
self.reader.read_to_end(name)
@@ -751,7 +757,7 @@ where
751757
{
752758
// Try to go to the next `<tag ...>...</tag>` or `<tag .../>`
753759
if let Some(e) = self.next_start()? {
754-
let name = e.name().to_vec();
760+
let name = e.name().as_ref().to_vec();
755761
let map = map::MapAccess::new(self, e, fields)?;
756762
let value = visitor.visit_map(map)?;
757763
self.read_to_end(&name)?;
@@ -785,11 +791,11 @@ where
785791
{
786792
match self.next()? {
787793
DeEvent::Start(s) => {
788-
self.read_to_end(s.name())?;
794+
self.read_to_end(s.name().as_ref())?;
789795
visitor.visit_unit()
790796
}
791797
DeEvent::Text(_) | DeEvent::CData(_) => visitor.visit_unit(),
792-
DeEvent::End(e) => Err(DeError::UnexpectedEnd(e.name().to_owned())),
798+
DeEvent::End(e) => Err(DeError::UnexpectedEnd(e.name().as_ref().to_owned())),
793799
DeEvent::Eof => Err(DeError::UnexpectedEof),
794800
}
795801
}
@@ -892,8 +898,8 @@ where
892898
V: Visitor<'de>,
893899
{
894900
match self.next()? {
895-
DeEvent::Start(e) => self.read_to_end(e.name())?,
896-
DeEvent::End(e) => return Err(DeError::UnexpectedEnd(e.name().to_owned())),
901+
DeEvent::Start(e) => self.read_to_end(e.name().as_ref())?,
902+
DeEvent::End(e) => return Err(DeError::UnexpectedEnd(e.name().as_ref().to_owned())),
897903
DeEvent::Eof => return Err(DeError::UnexpectedEof),
898904
_ => (),
899905
}

src/de/seq.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ pub fn not_in(
1515
decoder: Decoder,
1616
) -> Result<bool, DeError> {
1717
#[cfg(not(feature = "encoding"))]
18-
let tag = Cow::Borrowed(decoder.decode(start.name())?);
18+
let tag = Cow::Borrowed(decoder.decode(start.name().into_inner())?);
1919

2020
#[cfg(feature = "encoding")]
21-
let tag = decoder.decode(start.name());
21+
let tag = decoder.decode(start.name().into_inner());
2222

2323
Ok(fields.iter().all(|&field| field != tag.as_ref()))
2424
}

src/de/var.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ where
3838
DeEvent::Text(t) => EscapedDeserializer::new(Cow::Borrowed(t), decoder, true),
3939
// Escape sequences does not processed inside CDATA section
4040
DeEvent::CData(t) => EscapedDeserializer::new(Cow::Borrowed(t), decoder, false),
41-
DeEvent::Start(e) => EscapedDeserializer::new(Cow::Borrowed(e.name()), decoder, false),
41+
DeEvent::Start(e) => {
42+
EscapedDeserializer::new(Cow::Borrowed(e.name().into_inner()), decoder, false)
43+
}
4244
_ => {
4345
return Err(DeError::Unsupported(
4446
"Invalid event for Enum, expecting `Text` or `Start`",
@@ -65,7 +67,7 @@ where
6567

6668
fn unit_variant(self) -> Result<(), DeError> {
6769
match self.de.next()? {
68-
DeEvent::Start(e) => self.de.read_to_end(e.name()),
70+
DeEvent::Start(e) => self.de.read_to_end(e.name().as_ref()),
6971
DeEvent::Text(_) | DeEvent::CData(_) => Ok(()),
7072
_ => unreachable!(),
7173
}

src/events/mod.rs

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,14 @@ use encoding_rs::Encoding;
4141
use std::{borrow::Cow, collections::HashMap, io::BufRead, ops::Deref, str::from_utf8};
4242

4343
use crate::escape::{do_unescape, escape, partial_escape};
44+
use crate::name::{LocalName, QName};
4445
use crate::utils::write_cow_string;
4546
use crate::{errors::Error, errors::Result, reader::Reader};
4647
use attributes::{Attribute, Attributes};
4748

4849
#[cfg(feature = "serialize")]
4950
use crate::escape::EscapeError;
5051

51-
use memchr;
52-
5352
/// Opening tag data (`Event::Start`), with optional attributes.
5453
///
5554
/// `<name attr="value">`.
@@ -156,22 +155,22 @@ impl<'a> BytesStart<'a> {
156155

157156
/// Creates new paired close tag
158157
pub fn to_end(&self) -> BytesEnd {
159-
BytesEnd::borrowed(self.name())
158+
BytesEnd::borrowed(self.name().into_inner())
160159
}
161160

162-
/// Gets the undecoded raw tag name as a `&[u8]`.
161+
/// Gets the undecoded raw tag name, as present in the input stream.
163162
#[inline]
164-
pub fn name(&self) -> &[u8] {
165-
&self.buf[..self.name_len]
163+
pub fn name(&self) -> QName {
164+
QName(&self.buf[..self.name_len])
166165
}
167166

168-
/// Gets the undecoded raw local tag name (excluding namespace) as a `&[u8]`.
167+
/// Gets the undecoded raw local tag name (excluding namespace) as present
168+
/// in the input stream.
169169
///
170170
/// All content up to and including the first `:` character is removed from the tag name.
171171
#[inline]
172-
pub fn local_name(&self) -> &[u8] {
173-
let name = self.name();
174-
memchr::memchr(b':', name).map_or(name, |i| &name[i + 1..])
172+
pub fn local_name(&self) -> LocalName {
173+
self.name().into()
175174
}
176175

177176
/// Gets the unescaped tag name.
@@ -641,22 +640,19 @@ impl<'a> BytesEnd<'a> {
641640
}
642641
}
643642

644-
/// Gets `BytesEnd` event name
643+
/// Gets the undecoded raw tag name, as present in the input stream.
645644
#[inline]
646-
pub fn name(&self) -> &[u8] {
647-
&*self.name
645+
pub fn name(&self) -> QName {
646+
QName(&*self.name)
648647
}
649648

650-
/// local name (excluding namespace) as &[u8] (without eventual attributes)
651-
/// returns the name() with any leading namespace removed (all content up to
652-
/// and including the first ':' character)
649+
/// Gets the undecoded raw local tag name (excluding namespace) as present
650+
/// in the input stream.
651+
///
652+
/// All content up to and including the first `:` character is removed from the tag name.
653653
#[inline]
654-
pub fn local_name(&self) -> &[u8] {
655-
if let Some(i) = self.name().iter().position(|b| *b == b':') {
656-
&self.name()[i + 1..]
657-
} else {
658-
self.name()
659-
}
654+
pub fn local_name(&self) -> LocalName {
655+
self.name().into()
660656
}
661657
}
662658

@@ -1179,12 +1175,12 @@ mod test {
11791175
loop {
11801176
match rdr.read_event(&mut buf).expect("unable to read xml event") {
11811177
Event::Start(ref e) => parsed_local_names.push(
1182-
from_utf8(e.local_name())
1178+
from_utf8(e.local_name().as_ref())
11831179
.expect("unable to build str from local_name")
11841180
.to_string(),
11851181
),
11861182
Event::End(ref e) => parsed_local_names.push(
1187-
from_utf8(e.local_name())
1183+
from_utf8(e.local_name().as_ref())
11881184
.expect("unable to build str from local_name")
11891185
.to_string(),
11901186
),
@@ -1206,21 +1202,21 @@ mod test {
12061202
fn bytestart_create() {
12071203
let b = BytesStart::owned_name("test");
12081204
assert_eq!(b.len(), 4);
1209-
assert_eq!(b.name(), b"test");
1205+
assert_eq!(b.name(), QName(b"test"));
12101206
}
12111207

12121208
#[test]
12131209
fn bytestart_set_name() {
12141210
let mut b = BytesStart::owned_name("test");
12151211
assert_eq!(b.len(), 4);
1216-
assert_eq!(b.name(), b"test");
1212+
assert_eq!(b.name(), QName(b"test"));
12171213
assert_eq!(b.attributes_raw(), b"");
12181214
b.push_attribute(("x", "a"));
12191215
assert_eq!(b.len(), 10);
12201216
assert_eq!(b.attributes_raw(), b" x=\"a\"");
12211217
b.set_name(b"g");
12221218
assert_eq!(b.len(), 7);
1223-
assert_eq!(b.name(), b"g");
1219+
assert_eq!(b.name(), QName(b"g"));
12241220
}
12251221

12261222
#[test]
@@ -1231,6 +1227,6 @@ mod test {
12311227
b.clear_attributes();
12321228
assert!(b.attributes().next().is_none());
12331229
assert_eq!(b.len(), 4);
1234-
assert_eq!(b.name(), b"test");
1230+
assert_eq!(b.name(), QName(b"test"));
12351231
}
12361232
}

0 commit comments

Comments
 (0)