From 553a9ef20344b28cb6dbce904d709e52c27d2171 Mon Sep 17 00:00:00 2001 From: Daniel Alley Date: Sun, 14 Aug 2022 00:28:28 -0400 Subject: [PATCH] Convert namespace-related structs to str --- benches/microbenches.rs | 2 +- examples/custom_entities.rs | 2 +- examples/nested_readers.rs | 13 +- examples/read_buffered.rs | 4 +- examples/read_texts.rs | 4 +- src/de/escape.rs | 16 +- src/de/map.rs | 52 +++--- src/de/mod.rs | 39 ++--- src/de/seq.rs | 35 ++-- src/de/simple_type.rs | 7 +- src/de/var.rs | 13 +- src/errors.rs | 17 +- src/events/attributes.rs | 207 ++++++++++++----------- src/events/mod.rs | 23 ++- src/name.rs | 298 +++++++++++++++++----------------- src/reader/buffered_reader.rs | 2 +- src/reader/mod.rs | 8 +- src/reader/ns_reader.rs | 38 ++--- src/reader/slice_reader.rs | 2 +- src/writer.rs | 4 +- tests/namespaces.rs | 60 +++---- tests/serde-de.rs | 2 +- tests/test.rs | 14 +- tests/unit_tests.rs | 18 +- tests/xmlrs_reader_tests.rs | 15 +- 25 files changed, 424 insertions(+), 471 deletions(-) diff --git a/benches/microbenches.rs b/benches/microbenches.rs index 65a98f4f..e1a034fe 100644 --- a/benches/microbenches.rs +++ b/benches/microbenches.rs @@ -224,7 +224,7 @@ fn attributes(c: &mut Criterion) { let mut count = criterion::black_box(0); loop { match r.read_event() { - Ok(Event::Empty(e)) if e.name() == QName(b"player") => { + Ok(Event::Empty(e)) if e.name() == QName("player") => { for name in ["num", "status", "avg"] { if let Some(_attr) = e.try_get_attribute(name).unwrap() { count += 1 diff --git a/examples/custom_entities.rs b/examples/custom_entities.rs index 16f03482..44dde1bc 100644 --- a/examples/custom_entities.rs +++ b/examples/custom_entities.rs @@ -41,7 +41,7 @@ fn main() -> Result<(), Box> { } } Ok(Event::Start(ref e)) => match e.name().as_ref() { - b"test" => { + "test" => { let attributes = e .attributes() .map(|a| { diff --git a/examples/nested_readers.rs b/examples/nested_readers.rs index 1e5b9c71..fda48a3c 100644 --- a/examples/nested_readers.rs +++ b/examples/nested_readers.rs @@ -22,7 +22,7 @@ fn main() -> Result<(), quick_xml::Error> { loop { match reader.read_event_into(&mut buf)? { Event::Start(element) => match element.name().as_ref() { - b"w:tbl" => { + "w:tbl" => { count += 1; let mut stats = TableStat { index: count, @@ -35,20 +35,17 @@ fn main() -> Result<(), quick_xml::Error> { skip_buf.clear(); match reader.read_event_into(&mut skip_buf)? { Event::Start(element) => match element.name().as_ref() { - b"w:tr" => { + "w:tr" => { stats.rows.push(vec![]); row_index = stats.rows.len() - 1; } - b"w:tc" => { - stats.rows[row_index].push( - String::from_utf8(element.name().as_ref().to_vec()) - .unwrap(), - ); + "w:tc" => { + stats.rows[row_index].push(element.name().as_ref().to_owned()); } _ => {} }, Event::End(element) => { - if element.name().as_ref() == b"w:tbl" { + if element.name().as_ref() == "w:tbl" { found_tables.push(stats); break; } diff --git a/examples/read_buffered.rs b/examples/read_buffered.rs index 25b28ee2..2058978e 100644 --- a/examples/read_buffered.rs +++ b/examples/read_buffered.rs @@ -17,9 +17,7 @@ fn main() -> Result<(), quick_xml::Error> { loop { match reader.read_event_into(&mut buf) { Ok(Event::Start(ref e)) => { - let name = e.name(); - let name = reader.decoder().decode(name.as_ref())?; - println!("read start event {:?}", name.as_ref()); + println!("read start event {:?}", e.name().as_ref()); count += 1; } Ok(Event::Eof) => break, // exits the loop when reaching end of file diff --git a/examples/read_texts.rs b/examples/read_texts.rs index 16ecdad8..26f026c2 100644 --- a/examples/read_texts.rs +++ b/examples/read_texts.rs @@ -12,10 +12,10 @@ fn main() { let mut txt = Vec::new(); loop { match reader.read_event() { - Ok(Event::Start(ref e)) if e.name().as_ref() == b"tag2" => { + Ok(Event::Start(ref e)) if e.name().as_ref() == "tag2" => { txt.push( reader - .read_text(QName(b"tag2")) + .read_text_into(QName("tag2"), &mut Vec::new()) .expect("Cannot decode text value"), ); println!("{:?}", txt); diff --git a/src/de/escape.rs b/src/de/escape.rs index 191df90b..3c3ccc1a 100644 --- a/src/de/escape.rs +++ b/src/de/escape.rs @@ -1,7 +1,6 @@ //! Serde `Deserializer` module use crate::de::deserialize_bool; -use crate::encoding::Decoder; use crate::errors::serialize::DeError; use crate::escape::unescape; use serde::de::{DeserializeSeed, EnumAccess, VariantAccess, Visitor}; @@ -17,17 +16,15 @@ use std::borrow::Cow; /// anyway #[derive(Clone, Debug)] pub struct EscapedDeserializer<'a> { - decoder: Decoder, /// Possible escaped value of text/CDATA or attribute value - escaped_value: Cow<'a, [u8]>, + escaped_value: Cow<'a, str>, /// If `true`, value requires unescaping before using escaped: bool, } impl<'a> EscapedDeserializer<'a> { - pub fn new(escaped_value: Cow<'a, [u8]>, decoder: Decoder, escaped: bool) -> Self { + pub fn new(escaped_value: Cow<'a, str>, escaped: bool) -> Self { EscapedDeserializer { - decoder, escaped_value, escaped, } @@ -40,7 +37,7 @@ macro_rules! deserialize_num { where V: Visitor<'de>, { - let value = self.decoder.decode(self.escaped_value.as_ref())?.parse()?; + let value = self.escaped_value.as_ref().parse()?; visitor.$visit(value) } @@ -61,14 +58,13 @@ impl<'de, 'a> serde::Deserializer<'de> for EscapedDeserializer<'a> { where V: Visitor<'de>, { - let decoded = self.decoder.decode(&self.escaped_value)?; if self.escaped { - match unescape(&decoded)? { + match unescape(&self.escaped_value)? { Cow::Borrowed(s) => visitor.visit_str(s), Cow::Owned(s) => visitor.visit_string(s), } } else { - match decoded { + match self.escaped_value { Cow::Borrowed(s) => visitor.visit_str(s), Cow::Owned(s) => visitor.visit_string(s), } @@ -104,7 +100,7 @@ impl<'de, 'a> serde::Deserializer<'de> for EscapedDeserializer<'a> { where V: Visitor<'de>, { - deserialize_bool(self.escaped_value.as_ref(), self.decoder, visitor) + deserialize_bool(self.escaped_value.as_ref(), visitor) } fn deserialize_char(self, visitor: V) -> Result diff --git a/src/de/map.rs b/src/de/map.rs index 26d5532b..499820c2 100644 --- a/src/de/map.rs +++ b/src/de/map.rs @@ -231,15 +231,13 @@ where // FIXME: There error positions counted from the start of tag name - need global position let slice = &self.start.buf; - let decoder = self.de.reader.decoder(); if let Some(a) = self.iter.next(slice).transpose()? { // try getting map from attributes (key= "value") let (key, value) = a.into(); self.source = ValueSource::Attribute(value.unwrap_or_default()); seed.deserialize(EscapedDeserializer::new( - Cow::Borrowed(&slice[key]), - decoder, + Cow::Borrowed(std::str::from_utf8(&slice[key]).expect("fixme dalley")), false, )) .map(Some) @@ -269,33 +267,32 @@ where // } // TODO: This should be handled by #[serde(flatten)] // See https://github.com/serde-rs/serde/issues/1905 - DeEvent::Start(e) if self.has_value_field && not_in(self.fields, e, decoder)? => { + DeEvent::Start(e) if self.has_value_field && not_in(self.fields, e)? => { self.source = ValueSource::Content; seed.deserialize(INNER_VALUE.into_deserializer()).map(Some) } DeEvent::Start(e) => { self.source = ValueSource::Nested; - let key = if let Some(p) = self - .unflatten_fields - .iter() - .position(|f| e.name().as_ref() == &f[UNFLATTEN_PREFIX.len()..]) - { - // Used to deserialize elements, like: - // - // test - // - // - // into - // - // struct Root { - // #[serde(rename = "$unflatten=xxx")] - // xxx: String, - // } - seed.deserialize(self.unflatten_fields.remove(p).into_deserializer()) - } else { - let name = Cow::Borrowed(e.local_name().into_inner()); - seed.deserialize(EscapedDeserializer::new(name, decoder, false)) - }; + let key = + if let Some(p) = self.unflatten_fields.iter().position(|f| { + e.name().as_ref().as_bytes() == &f[UNFLATTEN_PREFIX.len()..] + }) { + // Used to deserialize elements, like: + // + // test + // + // + // into + // + // struct Root { + // #[serde(rename = "$unflatten=xxx")] + // xxx: String, + // } + seed.deserialize(self.unflatten_fields.remove(p).into_deserializer()) + } else { + let name = Cow::Borrowed(e.local_name().into_inner()); + seed.deserialize(EscapedDeserializer::new(name, false)) + }; key.map(Some) } // Stop iteration after reaching a closing tag @@ -616,18 +613,17 @@ where where T: DeserializeSeed<'de>, { - let decoder = self.map.de.reader.decoder(); loop { break match self.map.de.peek()? { // If we see a tag that we not interested, skip it #[cfg(feature = "overlapped-lists")] - DeEvent::Start(e) if !self.filter.is_suitable(&e, decoder)? => { + DeEvent::Start(e) if !self.filter.is_suitable(&e)? => { self.map.de.skip()?; continue; } // Stop iteration when list elements ends #[cfg(not(feature = "overlapped-lists"))] - DeEvent::Start(e) if !self.filter.is_suitable(&e, decoder)? => Ok(None), + DeEvent::Start(e) if !self.filter.is_suitable(&e)? => Ok(None), // Stop iteration after reaching a closing tag DeEvent::End(e) if e.name() == self.map.start.name() => Ok(None), diff --git a/src/de/mod.rs b/src/de/mod.rs index 56bf73d5..09cdd540 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -325,30 +325,12 @@ where } } -fn deserialize_bool<'de, V>(value: &[u8], decoder: Decoder, visitor: V) -> Result +fn deserialize_bool<'de, V>(value: &str, visitor: V) -> Result where V: Visitor<'de>, { - #[cfg(feature = "encoding")] - { - let value = decoder.decode(value)?; - // No need to unescape because valid boolean representations cannot be escaped - str2bool(value.as_ref(), visitor) - } - - #[cfg(not(feature = "encoding"))] - { - // No need to unescape because valid boolean representations cannot be escaped - match value { - b"true" | b"1" | b"True" | b"TRUE" | b"t" | b"Yes" | b"YES" | b"yes" | b"y" => { - visitor.visit_bool(true) - } - b"false" | b"0" | b"False" | b"FALSE" | b"f" | b"No" | b"NO" | b"no" | b"n" => { - visitor.visit_bool(false) - } - e => Err(DeError::InvalidBoolean(decoder.decode(e)?.into())), - } - } + // No need to unescape because valid boolean representations cannot be escaped + str2bool(value.as_ref(), visitor) } impl<'de, R> Deserializer<'de, R> @@ -738,10 +720,9 @@ where { // Try to go to the next `...` or `` if let Some(e) = self.next_start()? { - let name = e.name().as_ref().to_vec(); - let map = map::MapAccess::new(self, e, fields)?; + let map = map::MapAccess::new(self, e.clone(), fields)?; let value = visitor.visit_map(map)?; - self.read_to_end(QName(&name))?; + self.read_to_end(e.name())?; Ok(value) } else { Err(DeError::ExpectedStart) @@ -1182,7 +1163,7 @@ mod tests { // // assert_eq!(de.next().unwrap(), Start(BytesStart::new("target"))); - de.read_to_end(QName(b"target")).unwrap(); + de.read_to_end(QName("target")).unwrap(); assert_eq!(de.read, vec![]); assert_eq!( de.write, @@ -1219,7 +1200,7 @@ mod tests { assert_eq!(de.write, vec![]); assert_eq!(de.next().unwrap(), Start(BytesStart::new("skip"))); - de.read_to_end(QName(b"skip")).unwrap(); + de.read_to_end(QName("skip")).unwrap(); assert_eq!(de.next().unwrap(), End(BytesEnd::new("root"))); assert_eq!(de.next().unwrap(), Eof); @@ -1477,7 +1458,7 @@ mod tests { de.next().unwrap(), Start(BytesStart::from_content(r#"tag a="1""#, 3)) ); - assert_eq!(de.read_to_end(QName(b"tag")).unwrap(), ()); + assert_eq!(de.read_to_end(QName("tag")).unwrap(), ()); assert_eq!( de.next().unwrap(), @@ -1487,7 +1468,7 @@ mod tests { assert_eq!(de.next().unwrap(), End(BytesEnd::new("tag"))); assert_eq!(de.next().unwrap(), Start(BytesStart::new("self-closed"))); - assert_eq!(de.read_to_end(QName(b"self-closed")).unwrap(), ()); + assert_eq!(de.read_to_end(QName("self-closed")).unwrap(), ()); assert_eq!(de.next().unwrap(), End(BytesEnd::new("root"))); assert_eq!(de.next().unwrap(), Eof); @@ -1588,7 +1569,7 @@ mod tests { reader.next().unwrap(), DeEvent::Start(BytesStart::from_content("item ", 4)) ); - reader.read_to_end(QName(b"item")).unwrap(); + reader.read_to_end(QName("item")).unwrap(); assert_eq!(reader.next().unwrap(), DeEvent::Eof); } diff --git a/src/de/seq.rs b/src/de/seq.rs index 00ad240e..c8c6e756 100644 --- a/src/de/seq.rs +++ b/src/de/seq.rs @@ -1,20 +1,12 @@ use crate::de::{DeError, DeEvent, Deserializer, XmlRead}; -use crate::encoding::Decoder; use crate::events::BytesStart; use serde::de::{DeserializeSeed, SeqAccess}; -/// Check if tag `start` is included in the `fields` list. `decoder` is used to -/// get a string representation of a tag. +/// Check if tag `start` is included in the `fields` list. /// /// Returns `true`, if `start` is not in the `fields` list and `false` otherwise. -pub fn not_in( - fields: &'static [&'static str], - start: &BytesStart, - decoder: Decoder, -) -> Result { - let tag = decoder.decode(start.name().into_inner())?; - - Ok(fields.iter().all(|&field| field != tag.as_ref())) +pub fn not_in(fields: &'static [&'static str], start: &BytesStart) -> Result { + Ok(fields.iter().all(|&field| field != start.name().as_ref())) } /// A filter that determines, what tags should form a sequence. @@ -59,10 +51,10 @@ pub enum TagFilter<'de> { } impl<'de> TagFilter<'de> { - pub fn is_suitable(&self, start: &BytesStart, decoder: Decoder) -> Result { + pub fn is_suitable(&self, start: &BytesStart) -> Result { match self { Self::Include(n) => Ok(n.name() == start.name()), - Self::Exclude(fields) => not_in(fields, start, decoder), + Self::Exclude(fields) => not_in(fields, start), } } } @@ -132,18 +124,17 @@ where where T: DeserializeSeed<'de>, { - let decoder = self.de.reader.decoder(); loop { break match self.de.peek()? { // If we see a tag that we not interested, skip it #[cfg(feature = "overlapped-lists")] - DeEvent::Start(e) if !self.filter.is_suitable(e, decoder)? => { + DeEvent::Start(e) if !self.filter.is_suitable(e)? => { self.de.skip()?; continue; } // Stop iteration when list elements ends #[cfg(not(feature = "overlapped-lists"))] - DeEvent::Start(e) if !self.filter.is_suitable(e, decoder)? => Ok(None), + DeEvent::Start(e) if !self.filter.is_suitable(e)? => Ok(None), DeEvent::End(_) => Ok(None), DeEvent::Eof => Ok(None), @@ -158,13 +149,7 @@ where fn test_not_in() { let tag = BytesStart::new("tag"); - assert_eq!(not_in(&[], &tag, Decoder::utf8()).unwrap(), true); - assert_eq!( - not_in(&["no", "such", "tags"], &tag, Decoder::utf8()).unwrap(), - true - ); - assert_eq!( - not_in(&["some", "tag", "included"], &tag, Decoder::utf8()).unwrap(), - false - ); + assert_eq!(not_in(&[], &tag).unwrap(), true); + assert_eq!(not_in(&["no", "such", "tags"], &tag).unwrap(), true); + assert_eq!(not_in(&["some", "tag", "included"], &tag).unwrap(), false); } diff --git a/src/de/simple_type.rs b/src/de/simple_type.rs index 580c6312..1d3a9baa 100644 --- a/src/de/simple_type.rs +++ b/src/de/simple_type.rs @@ -590,7 +590,10 @@ impl<'de, 'a> Deserializer<'de> for SimpleTypeDeserializer<'de, 'a> { where V: Visitor<'de>, { - deserialize_bool(&self.content, self.decoder, visitor) + deserialize_bool( + std::str::from_utf8(self.content.as_ref()).expect("fixme dalley"), + visitor, + ) } deserialize_num!(deserialize_i8 => visit_i8); @@ -1210,7 +1213,7 @@ mod tests { simple!(utf8, ignored_any: Any = "any data" => Any(IgnoredAny)); } - #[cfg(feature = "encoding")] + #[cfg(feature = "encoding-disabled")] // TODO: dalley mod utf16 { use super::*; use pretty_assertions::assert_eq; diff --git a/src/de/var.rs b/src/de/var.rs index 513e896d..fe0ea63a 100644 --- a/src/de/var.rs +++ b/src/de/var.rs @@ -33,13 +33,18 @@ where where V: DeserializeSeed<'de>, { - let decoder = self.de.reader.decoder(); let de = match self.de.peek()? { - DeEvent::Text(t) => EscapedDeserializer::new(Cow::Borrowed(t), decoder, true), + DeEvent::Text(t) => EscapedDeserializer::new( + Cow::Borrowed(std::str::from_utf8(t).expect("fixme dalley")), + true, + ), // Escape sequences does not processed inside CDATA section - DeEvent::CData(t) => EscapedDeserializer::new(Cow::Borrowed(t), decoder, false), + DeEvent::CData(t) => EscapedDeserializer::new( + Cow::Borrowed(std::str::from_utf8(t).expect("fixme dalley")), + false, + ), DeEvent::Start(e) => { - EscapedDeserializer::new(Cow::Borrowed(e.local_name().into_inner()), decoder, false) + EscapedDeserializer::new(Cow::Borrowed(e.local_name().into_inner()), false) } _ => { return Err(DeError::Unsupported( diff --git a/src/errors.rs b/src/errors.rs index 8d00763f..aad3474d 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -2,7 +2,6 @@ use crate::escape::EscapeError; use crate::events::attributes::AttrError; -use crate::utils::write_byte_string; use std::str::Utf8Error; use std::string::FromUtf8Error; @@ -36,7 +35,7 @@ pub enum Error { /// Escape error EscapeError(EscapeError), /// Specified namespace prefix is unknown, cannot resolve namespace for it - UnknownPrefix(Vec), + UnknownPrefix(String), } impl From<::std::io::Error> for Error { @@ -105,11 +104,7 @@ impl std::fmt::Display for Error { ), Error::InvalidAttr(e) => write!(f, "error while parsing attribute: {}", e), Error::EscapeError(e) => write!(f, "{}", e), - Error::UnknownPrefix(prefix) => { - f.write_str("Unknown namespace prefix '")?; - write_byte_string(f, &prefix)?; - f.write_str("'") - } + Error::UnknownPrefix(prefix) => write!(f, "Unknown namespace prefix '{}'", &prefix), } } } @@ -159,7 +154,7 @@ pub mod serialize { /// Deserializer encounter a start tag with a specified name when it is /// not expecting. This happens when you try to deserialize a primitive /// value (numbers, strings, booleans) from an XML element. - UnexpectedStart(Vec), + UnexpectedStart(String), /// Deserializer encounter an end tag with a specified name when it is /// not expecting. Usually that should not be possible, because XML reader /// is not able to produce such stream of events that lead to this error. @@ -167,7 +162,7 @@ pub mod serialize { /// If you get this error this likely indicates and error in the `quick_xml`. /// Please open an issue at , provide /// your Rust code and XML input. - UnexpectedEnd(Vec), + UnexpectedEnd(String), /// Unexpected end of file UnexpectedEof, /// This error indicates that [`deserialize_struct`] was called, but there @@ -195,12 +190,12 @@ pub mod serialize { DeError::KeyNotRead => write!(f, "Invalid `Deserialize` implementation: `MapAccess::next_value[_seed]` was called before `MapAccess::next_key[_seed]`"), DeError::UnexpectedStart(e) => { f.write_str("Unexpected `Event::Start(")?; - write_byte_string(f, &e)?; + write_byte_string(f, &e.as_bytes())?; f.write_str(")`") } DeError::UnexpectedEnd(e) => { f.write_str("Unexpected `Event::End(")?; - write_byte_string(f, &e)?; + write_byte_string(f, &e.as_bytes())?; f.write_str(")`") } DeError::UnexpectedEof => write!(f, "Unexpected `Event::Eof`"), diff --git a/src/events/attributes.rs b/src/events/attributes.rs index ad938f9b..b8689a02 100644 --- a/src/events/attributes.rs +++ b/src/events/attributes.rs @@ -6,7 +6,7 @@ use crate::errors::Result as XmlResult; use crate::escape::{escape, unescape_with}; use crate::name::QName; use crate::reader::{is_whitespace, Reader}; -use crate::utils::{write_byte_string, write_cow_string, Bytes}; +use crate::utils::{write_cow_string, Bytes}; use std::fmt::{self, Debug, Display, Formatter}; use std::iter::FusedIterator; use std::{borrow::Cow, ops::Range}; @@ -98,9 +98,7 @@ impl<'a> Attribute<'a> { impl<'a> Debug for Attribute<'a> { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "Attribute {{ key: ")?; - write_byte_string(f, self.key.as_ref())?; - write!(f, ", value: ")?; + write!(f, "Attribute {{ key: {}, value: ", self.key.as_ref())?; write_cow_string(f, &self.value)?; write!(f, " }}") } @@ -121,7 +119,7 @@ impl<'a> From<(&'a [u8], &'a [u8])> for Attribute<'a> { /// ``` fn from(val: (&'a [u8], &'a [u8])) -> Attribute<'a> { Attribute { - key: QName(val.0), + key: QName(std::str::from_utf8(val.0).expect("fixme dalley")), value: Cow::from(val.1), } } @@ -142,7 +140,7 @@ impl<'a> From<(&'a str, &'a str)> for Attribute<'a> { /// ``` fn from(val: (&'a str, &'a str)) -> Attribute<'a> { Attribute { - key: QName(val.0.as_bytes()), + key: QName(val.0), value: match escape(val.1) { Cow::Borrowed(s) => Cow::Borrowed(s.as_bytes()), Cow::Owned(s) => Cow::Owned(s.into_bytes()), @@ -402,12 +400,13 @@ impl<'a> Attr<&'a [u8]> { /// Returns the key value #[inline] pub fn key(&self) -> QName<'a> { - QName(match self { + let key = match self { Attr::DoubleQ(key, _) => key, Attr::SingleQ(key, _) => key, Attr::Empty(key) => key, Attr::Unquoted(key, _) => key, - }) + }; + QName(std::str::from_utf8(key).expect("fixme dalley")) } /// Returns the attribute value. For [`Self::Empty`] variant an empty slice /// is returned according to the [HTML specification]. @@ -793,7 +792,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -809,7 +808,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -849,7 +848,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"'key'"), + key: QName("'key'"), value: Cow::Borrowed(b"value"), })) ); @@ -867,7 +866,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key&jey"), + key: QName("key&jey"), value: Cow::Borrowed(b"value"), })) ); @@ -900,14 +899,14 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"regular"), + key: QName("regular"), value: Cow::Borrowed(b"attribute"), })) ); @@ -923,14 +922,14 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"regular"), + key: QName("regular"), value: Cow::Borrowed(b"attribute"), })) ); @@ -949,7 +948,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"regular"), + key: QName("regular"), value: Cow::Borrowed(b"attribute"), })) ); @@ -968,7 +967,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"regular"), + key: QName("regular"), value: Cow::Borrowed(b"attribute"), })) ); @@ -986,14 +985,14 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"'key'"), + key: QName("'key'"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"regular"), + key: QName("regular"), value: Cow::Borrowed(b"attribute"), })) ); @@ -1011,14 +1010,14 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key&jey"), + key: QName("key&jey"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"regular"), + key: QName("regular"), value: Cow::Borrowed(b"attribute"), })) ); @@ -1095,7 +1094,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1111,7 +1110,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1151,7 +1150,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"'key'"), + key: QName("'key'"), value: Cow::Borrowed(b"value"), })) ); @@ -1169,7 +1168,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key&jey"), + key: QName("key&jey"), value: Cow::Borrowed(b"value"), })) ); @@ -1207,7 +1206,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1215,7 +1214,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -1232,7 +1231,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1240,7 +1239,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -1257,7 +1256,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1265,7 +1264,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -1282,7 +1281,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1290,7 +1289,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -1313,21 +1312,21 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"dup"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -1344,21 +1343,21 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"dup"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -1376,7 +1375,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1384,7 +1383,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -1402,7 +1401,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1410,7 +1409,7 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -1427,28 +1426,28 @@ mod xml { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"a"), + key: QName("a"), value: Cow::Borrowed(b"a"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"b"), + key: QName("b"), value: Cow::Borrowed(b"b"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"c"), + key: QName("c"), value: Cow::Borrowed(br#"cc"cc"#), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"d"), + key: QName("d"), value: Cow::Borrowed(b"dd'dd"), })) ); @@ -1480,7 +1479,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1496,7 +1495,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1512,7 +1511,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1528,7 +1527,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(&[]), })) ); @@ -1546,7 +1545,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"'key'"), + key: QName("'key'"), value: Cow::Borrowed(b"value"), })) ); @@ -1564,7 +1563,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key&jey"), + key: QName("key&jey"), value: Cow::Borrowed(b"value"), })) ); @@ -1597,14 +1596,14 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"regular"), + key: QName("regular"), value: Cow::Borrowed(b"attribute"), })) ); @@ -1620,14 +1619,14 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"regular"), + key: QName("regular"), value: Cow::Borrowed(b"attribute"), })) ); @@ -1643,14 +1642,14 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"regular"), + key: QName("regular"), value: Cow::Borrowed(b"attribute"), })) ); @@ -1666,14 +1665,14 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(&[]), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"regular"), + key: QName("regular"), value: Cow::Borrowed(b"attribute"), })) ); @@ -1691,14 +1690,14 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"'key'"), + key: QName("'key'"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"regular"), + key: QName("regular"), value: Cow::Borrowed(b"attribute"), })) ); @@ -1716,14 +1715,14 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key&jey"), + key: QName("key&jey"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"regular"), + key: QName("regular"), value: Cow::Borrowed(b"attribute"), })) ); @@ -1741,7 +1740,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"regular='attribute'"), })) ); @@ -1757,7 +1756,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"regular="), })) ); @@ -1766,7 +1765,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"'attribute'"), + key: QName("'attribute'"), value: Cow::Borrowed(&[]), })) ); @@ -1782,7 +1781,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"regular"), })) ); @@ -1791,7 +1790,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"='attribute'"), + key: QName("='attribute'"), value: Cow::Borrowed(&[]), })) ); @@ -1808,7 +1807,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"regular"), })) ); @@ -1817,7 +1816,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"="), + key: QName("="), value: Cow::Borrowed(&[]), })) ); @@ -1826,7 +1825,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"'attribute'"), + key: QName("'attribute'"), value: Cow::Borrowed(&[]), })) ); @@ -1848,7 +1847,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1864,7 +1863,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1880,7 +1879,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1896,7 +1895,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(&[]), })) ); @@ -1914,7 +1913,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"'key'"), + key: QName("'key'"), value: Cow::Borrowed(b"value"), })) ); @@ -1932,7 +1931,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key&jey"), + key: QName("key&jey"), value: Cow::Borrowed(b"value"), })) ); @@ -1970,7 +1969,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -1978,7 +1977,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -1995,7 +1994,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -2003,7 +2002,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -2020,7 +2019,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -2028,7 +2027,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -2045,7 +2044,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); @@ -2053,7 +2052,7 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -2076,21 +2075,21 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"dup"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -2107,21 +2106,21 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"dup"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -2138,21 +2137,21 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"dup"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -2169,21 +2168,21 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(b"value"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"key"), + key: QName("key"), value: Cow::Borrowed(&[]), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"another"), + key: QName("another"), value: Cow::Borrowed(b""), })) ); @@ -2200,28 +2199,28 @@ mod html { assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"a"), + key: QName("a"), value: Cow::Borrowed(b"a"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"b"), + key: QName("b"), value: Cow::Borrowed(b"b"), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"c"), + key: QName("c"), value: Cow::Borrowed(br#"cc"cc"#), })) ); assert_eq!( iter.next(), Some(Ok(Attribute { - key: QName(b"d"), + key: QName("d"), value: Cow::Borrowed(b"dd'dd"), })) ); diff --git a/src/events/mod.rs b/src/events/mod.rs index 2c1ae8bd..0c8dfa91 100644 --- a/src/events/mod.rs +++ b/src/events/mod.rs @@ -41,7 +41,6 @@ use encoding_rs::Encoding; use std::borrow::Cow; use std::fmt::{self, Debug, Formatter}; use std::ops::Deref; -use std::str::from_utf8; use crate::encoding::Decoder; use crate::errors::{Error, Result}; @@ -156,13 +155,13 @@ impl<'a> BytesStart<'a> { /// Creates new paired close tag pub fn to_end(&self) -> BytesEnd { - BytesEnd::wrap(self.name().into_inner().into()) + BytesEnd::new(self.name().as_ref().to_owned()) } /// Gets the undecoded raw tag name, as present in the input stream. #[inline] pub fn name(&self) -> QName { - QName(&self.buf[..self.name_len]) + QName(std::str::from_utf8(&self.buf[..self.name_len]).expect("fixme dalley")) } /// Gets the undecoded raw local tag name (excluding namespace) as present @@ -223,7 +222,7 @@ impl<'a> BytesStart<'a> { let a = attr.into(); let bytes = self.buf.to_mut(); bytes.push(b' '); - bytes.extend_from_slice(a.key.as_ref()); + bytes.extend_from_slice(a.key.as_ref().as_bytes()); bytes.extend_from_slice(b"=\""); bytes.extend_from_slice(&*a.value); bytes.push(b'"'); @@ -259,7 +258,7 @@ impl<'a> BytesStart<'a> { ) -> Result>> { for a in self.attributes() { let a = a?; - if a.key.as_ref() == attr_name.as_ref() { + if a.key.as_ref().as_bytes() == attr_name.as_ref() { return Ok(Some(a)); } } @@ -402,10 +401,10 @@ impl<'a> BytesDecl<'a> { pub fn version(&self) -> Result> { // The version *must* be the first thing in the declaration. match self.content.attributes().with_checks(false).next() { - Some(Ok(a)) if a.key.as_ref() == b"version" => Ok(a.value), + Some(Ok(a)) if a.key.as_ref() == "version" => Ok(a.value), // first attribute was not "version" Some(Ok(a)) => { - let found = from_utf8(a.key.as_ref())?.to_string(); + let found = a.key.as_ref().to_owned(); Err(Error::XmlDeclWithoutVersion(Some(found))) } // error parsing attributes @@ -574,7 +573,7 @@ impl<'a> BytesEnd<'a> { /// Gets the undecoded raw tag name, as present in the input stream. #[inline] pub fn name(&self) -> QName { - QName(&*self.name) + QName(std::str::from_utf8(&*self.name).expect("fixme dalley")) } /// Gets the undecoded raw local tag name (excluding namespace) as present @@ -970,21 +969,21 @@ mod test { fn bytestart_create() { let b = BytesStart::new("test"); assert_eq!(b.len(), 4); - assert_eq!(b.name(), QName(b"test")); + assert_eq!(b.name(), QName("test")); } #[test] fn bytestart_set_name() { let mut b = BytesStart::new("test"); assert_eq!(b.len(), 4); - assert_eq!(b.name(), QName(b"test")); + assert_eq!(b.name(), QName("test")); assert_eq!(b.attributes_raw(), b""); b.push_attribute(("x", "a")); assert_eq!(b.len(), 10); assert_eq!(b.attributes_raw(), b" x=\"a\""); b.set_name(b"g"); assert_eq!(b.len(), 7); - assert_eq!(b.name(), QName(b"g")); + assert_eq!(b.name(), QName("g")); } #[test] @@ -995,6 +994,6 @@ mod test { b.clear_attributes(); assert!(b.attributes().next().is_none()); assert_eq!(b.len(), 4); - assert_eq!(b.name(), QName(b"test")); + assert_eq!(b.name(), QName("test")); } } diff --git a/src/name.rs b/src/name.rs index ea304e02..868bcf0d 100644 --- a/src/name.rs +++ b/src/name.rs @@ -6,7 +6,6 @@ use crate::errors::{Error, Result}; use crate::events::attributes::Attribute; use crate::events::BytesStart; -use crate::utils::write_byte_string; use memchr::memchr; use std::convert::TryFrom; use std::fmt::{self, Debug, Formatter}; @@ -17,11 +16,11 @@ use std::fmt::{self, Debug, Formatter}; /// [qualified name]: https://www.w3.org/TR/xml-names11/#dt-qualname #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] -pub struct QName<'a>(pub &'a [u8]); +pub struct QName<'a>(pub &'a str); impl<'a> QName<'a> { /// Converts this name to an internal slice representation. #[inline(always)] - pub fn into_inner(self) -> &'a [u8] { + pub fn into_inner(self) -> &'a str { self.0 } @@ -34,11 +33,11 @@ impl<'a> QName<'a> { /// /// ``` /// # use quick_xml::name::QName; - /// let simple = QName(b"simple-name"); - /// assert_eq!(simple.local_name().as_ref(), b"simple-name"); + /// let simple = QName("simple-name"); + /// assert_eq!(simple.local_name().as_ref(), "simple-name"); /// - /// let qname = QName(b"namespace:simple-name"); - /// assert_eq!(qname.local_name().as_ref(), b"simple-name"); + /// let qname = QName("namespace:simple-name"); + /// assert_eq!(qname.local_name().as_ref(), "simple-name"); /// ``` pub fn local_name(&self) -> LocalName<'a> { LocalName(self.index().map_or(self.0, |i| &self.0[i + 1..])) @@ -52,11 +51,11 @@ impl<'a> QName<'a> { /// ``` /// # use std::convert::AsRef; /// # use quick_xml::name::QName; - /// let simple = QName(b"simple-name"); + /// let simple = QName("simple-name"); /// assert_eq!(simple.prefix(), None); /// - /// let qname = QName(b"prefix:simple-name"); - /// assert_eq!(qname.prefix().as_ref().map(|n| n.as_ref()), Some(b"prefix".as_ref())); + /// let qname = QName("prefix:simple-name"); + /// assert_eq!(qname.prefix().as_ref().map(|n| n.as_ref()), Some("prefix".as_ref())); /// ``` pub fn prefix(&self) -> Option> { self.index().map(|i| Prefix(&self.0[..i])) @@ -78,28 +77,28 @@ impl<'a> QName<'a> { /// /// ``` /// # use quick_xml::name::{QName, PrefixDeclaration}; - /// let qname = QName(b"xmlns"); + /// let qname = QName("xmlns"); /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Default)); /// - /// let qname = QName(b"xmlns:prefix"); - /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named(b"prefix"))); + /// let qname = QName("xmlns:prefix"); + /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named("prefix"))); /// /// // Be aware that this method does not check the validity of the prefix - it can be empty! - /// let qname = QName(b"xmlns:"); - /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named(b""))); + /// let qname = QName("xmlns:"); + /// assert_eq!(qname.as_namespace_binding(), Some(PrefixDeclaration::Named(""))); /// - /// let qname = QName(b"other-name"); + /// let qname = QName("other-name"); /// assert_eq!(qname.as_namespace_binding(), None); /// /// // https://www.w3.org/TR/xml-names11/#xmlReserved - /// let qname = QName(b"xmlns-reserved-name"); + /// let qname = QName("xmlns-reserved-name"); /// assert_eq!(qname.as_namespace_binding(), None); /// ``` pub fn as_namespace_binding(&self) -> Option> { - if self.0.starts_with(b"xmlns") { - return match self.0.get(5) { + if self.0.starts_with("xmlns") { + return match self.0.bytes().nth(5) { None => Some(PrefixDeclaration::Default), - Some(&b':') => Some(PrefixDeclaration::Named(&self.0[6..])), + Some(b':') => Some(PrefixDeclaration::Named(&self.0[6..])), _ => None, }; } @@ -109,19 +108,19 @@ impl<'a> QName<'a> { /// Returns the index in the name where prefix ended #[inline(always)] fn index(&self) -> Option { - memchr(b':', self.0) + memchr(b':', self.0.as_bytes()) } } + impl<'a> Debug for QName<'a> { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "QName(")?; - write_byte_string(f, self.0)?; - write!(f, ")") + write!(f, "QName({})", self.0) } } -impl<'a> AsRef<[u8]> for QName<'a> { + +impl<'a> AsRef for QName<'a> { #[inline] - fn as_ref(&self) -> &[u8] { + fn as_ref(&self) -> &str { self.0 } } @@ -134,27 +133,29 @@ impl<'a> AsRef<[u8]> for QName<'a> { /// [local (unqualified) name]: https://www.w3.org/TR/xml-names11/#dt-localname #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] -pub struct LocalName<'a>(&'a [u8]); +pub struct LocalName<'a>(&'a str); + impl<'a> LocalName<'a> { /// Converts this name to an internal slice representation. #[inline(always)] - pub fn into_inner(self) -> &'a [u8] { + pub fn into_inner(self) -> &'a str { self.0 } } + impl<'a> Debug for LocalName<'a> { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "LocalName(")?; - write_byte_string(f, self.0)?; - write!(f, ")") + write!(f, "LocalName({})", self.0) } } -impl<'a> AsRef<[u8]> for LocalName<'a> { + +impl<'a> AsRef for LocalName<'a> { #[inline] - fn as_ref(&self) -> &[u8] { + fn as_ref(&self) -> &str { self.0 } } + impl<'a> From> for LocalName<'a> { /// Creates `LocalName` from a [`QName`] /// @@ -163,11 +164,11 @@ impl<'a> From> for LocalName<'a> { /// ``` /// # use quick_xml::name::{LocalName, QName}; /// - /// let local: LocalName = QName(b"unprefixed").into(); - /// assert_eq!(local.as_ref(), b"unprefixed"); + /// let local: LocalName = QName("unprefixed").into(); + /// assert_eq!(local.as_ref(), "unprefixed"); /// - /// let local: LocalName = QName(b"some:prefix").into(); - /// assert_eq!(local.as_ref(), b"prefix"); + /// let local: LocalName = QName("some:prefix").into(); + /// assert_eq!(local.as_ref(), "prefix"); /// ``` #[inline] fn from(name: QName<'a>) -> Self { @@ -184,24 +185,25 @@ impl<'a> From> for LocalName<'a> { /// [namespace prefix]: https://www.w3.org/TR/xml-names11/#dt-prefix #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] -pub struct Prefix<'a>(&'a [u8]); +pub struct Prefix<'a>(&'a str); + impl<'a> Prefix<'a> { /// Extracts internal slice #[inline(always)] - pub fn into_inner(self) -> &'a [u8] { + pub fn into_inner(self) -> &'a str { self.0 } } + impl<'a> Debug for Prefix<'a> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "Prefix(")?; - write_byte_string(f, self.0)?; - write!(f, ")") + write!(f, "Prefix({})", self.0) } } -impl<'a> AsRef<[u8]> for Prefix<'a> { + +impl<'a> AsRef for Prefix<'a> { #[inline] - fn as_ref(&self) -> &[u8] { + fn as_ref(&self) -> &str { self.0 } } @@ -216,7 +218,7 @@ pub enum PrefixDeclaration<'a> { Default, /// XML attribute binds a specified prefix to a namespace. Corresponds to a /// `prefix` in `xmlns:prefix="..."`, which is stored as payload of this variant. - Named(&'a [u8]), + Named(&'a str), } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -226,7 +228,8 @@ pub enum PrefixDeclaration<'a> { /// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] -pub struct Namespace<'a>(pub &'a [u8]); +pub struct Namespace<'a>(pub &'a str); + impl<'a> Namespace<'a> { /// Converts this namespace to an internal slice representation. /// @@ -253,21 +256,21 @@ impl<'a> Namespace<'a> { /// [non-normalized]: https://www.w3.org/TR/REC-xml/#AVNormalize /// [IRI reference]: https://datatracker.ietf.org/doc/html/rfc3987 #[inline(always)] - pub fn into_inner(self) -> &'a [u8] { + pub fn into_inner(self) -> &'a str { self.0 } //TODO: implement value normalization and use it when comparing namespaces } + impl<'a> Debug for Namespace<'a> { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "Namespace(")?; - write_byte_string(f, self.0)?; - write!(f, ")") + write!(f, "Namespace({})", self.0) } } -impl<'a> AsRef<[u8]> for Namespace<'a> { + +impl<'a> AsRef for Namespace<'a> { #[inline] - fn as_ref(&self) -> &[u8] { + fn as_ref(&self) -> &str { self.0 } } @@ -291,18 +294,14 @@ pub enum ResolveResult<'ns> { /// [`Prefix`] resolved to the specified namespace Bound(Namespace<'ns>), /// Specified prefix was not found in scope - Unknown(Vec), + Unknown(String), } impl<'ns> Debug for ResolveResult<'ns> { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { Self::Unbound => write!(f, "Unbound"), Self::Bound(ns) => write!(f, "Bound({:?})", ns), - Self::Unknown(p) => { - write!(f, "Unknown(")?; - write_byte_string(f, p)?; - write!(f, ")") - } + Self::Unknown(p) => write!(f, "Unknown({})", p), } } } @@ -364,7 +363,7 @@ impl NamespaceEntry { /// Get the namespace prefix, bound to this namespace declaration, or `None`, /// if this declaration is for default namespace (`xmlns="..."`). #[inline] - fn prefix<'b>(&self, ns_buffer: &'b [u8]) -> Option> { + fn prefix<'b>(&self, ns_buffer: &'b str) -> Option> { if self.prefix_len == 0 { None } else { @@ -377,7 +376,7 @@ impl NamespaceEntry { /// Returns `None` if namespace for this prefix was explicitly removed from /// scope, using `xmlns[:prefix]=""` #[inline] - fn namespace<'ns>(&self, buffer: &'ns [u8]) -> ResolveResult<'ns> { + fn namespace<'ns>(&self, buffer: &'ns str) -> ResolveResult<'ns> { if self.value_len == 0 { ResolveResult::Unbound } else { @@ -404,17 +403,18 @@ impl NamespaceResolver { /// the specified start element. /// /// [namespace binding]: https://www.w3.org/TR/xml-names11/#dt-NSDecl - pub fn push(&mut self, start: &BytesStart, buffer: &mut Vec) { + pub fn push(&mut self, start: &BytesStart, buffer: &mut String) { self.nesting_level += 1; let level = self.nesting_level; // adds new namespaces for attributes starting with 'xmlns:' and for the 'xmlns' // (default namespace) attribute. for a in start.attributes().with_checks(false) { if let Ok(Attribute { key: k, value: v }) = a { + let v = std::str::from_utf8(&v).expect("fixme dalley"); match k.as_namespace_binding() { Some(PrefixDeclaration::Default) => { let start = buffer.len(); - buffer.extend_from_slice(&*v); + buffer.push_str(&*v); self.bindings.push(NamespaceEntry { start, prefix_len: 0, @@ -424,8 +424,8 @@ impl NamespaceResolver { } Some(PrefixDeclaration::Named(prefix)) => { let start = buffer.len(); - buffer.extend_from_slice(prefix); - buffer.extend_from_slice(&*v); + buffer.push_str(prefix); + buffer.push_str(&*v); self.bindings.push(NamespaceEntry { start, prefix_len: prefix.len(), @@ -445,7 +445,7 @@ impl NamespaceResolver { /// last call to [`Self::push()`]. /// /// [namespace binding]: https://www.w3.org/TR/xml-names11/#dt-NSDecl - pub fn pop(&mut self, buffer: &mut Vec) { + pub fn pop(&mut self, buffer: &mut String) { self.nesting_level -= 1; let current_level = self.nesting_level; // from the back (most deeply nested scope), look for the first scope that is still valid @@ -483,7 +483,7 @@ impl NamespaceResolver { pub fn resolve<'n, 'ns>( &self, name: QName<'n>, - buffer: &'ns [u8], + buffer: &'ns str, use_default: bool, ) -> (ResolveResult<'ns>, LocalName<'n>) { let (local_name, prefix) = name.decompose(); @@ -505,14 +505,14 @@ impl NamespaceResolver { /// [namespace name]: https://www.w3.org/TR/xml-names11/#dt-NSName /// [unbound]: https://www.w3.org/TR/xml-names11/#scoping #[inline] - pub fn find<'ns>(&self, element_name: QName, buffer: &'ns [u8]) -> ResolveResult<'ns> { + pub fn find<'ns>(&self, element_name: QName, buffer: &'ns str) -> ResolveResult<'ns> { self.resolve_prefix(element_name.prefix(), buffer, true) } fn resolve_prefix<'ns>( &self, prefix: Option, - buffer: &'ns [u8], + buffer: &'ns str, use_default: bool, ) -> ResolveResult<'ns> { self.bindings @@ -542,7 +542,7 @@ impl NamespaceResolver { #[inline] fn maybe_unknown(prefix: Option) -> ResolveResult<'static> { match prefix { - Some(p) => ResolveResult::Unknown(p.into_inner().to_vec()), + Some(p) => ResolveResult::Unknown(p.into_inner().to_owned()), None => ResolveResult::Unbound, } } @@ -568,31 +568,31 @@ mod namespaces { /// Basic tests that checks that basic resolver functionality is working #[test] fn basic() { - let name = QName(b"simple"); - let ns = Namespace(b"default"); + let name = QName("simple"); + let ns = Namespace("default"); let mut resolver = NamespaceResolver::default(); - let mut buffer = Vec::new(); + let mut buffer = String::new(); resolver.push( &BytesStart::from_content(" xmlns='default'", 0), &mut buffer, ); - assert_eq!(buffer, b"default"); + assert_eq!(buffer, "default"); // Check that tags without namespaces does not change result resolver.push(&BytesStart::from_content("", 0), &mut buffer); - assert_eq!(buffer, b"default"); + assert_eq!(buffer, "default"); resolver.pop(&mut buffer); - assert_eq!(buffer, b"default"); + assert_eq!(buffer, "default"); assert_eq!( resolver.resolve(name, &buffer, true), - (Bound(ns), LocalName(b"simple")) + (Bound(ns), LocalName("simple")) ); assert_eq!( resolver.resolve(name, &buffer, false), - (Unbound, LocalName(b"simple")) + (Unbound, LocalName("simple")) ); assert_eq!(resolver.find(name, &buffer), Bound(ns)); } @@ -600,36 +600,36 @@ mod namespaces { /// Test adding a second level of namespaces, which replaces the previous binding #[test] fn override_namespace() { - let name = QName(b"simple"); - let old_ns = Namespace(b"old"); - let new_ns = Namespace(b"new"); + let name = QName("simple"); + let old_ns = Namespace("old"); + let new_ns = Namespace("new"); let mut resolver = NamespaceResolver::default(); - let mut buffer = Vec::new(); + let mut buffer = String::new(); resolver.push(&BytesStart::from_content(" xmlns='old'", 0), &mut buffer); resolver.push(&BytesStart::from_content(" xmlns='new'", 0), &mut buffer); - assert_eq!(buffer, b"oldnew"); + assert_eq!(buffer, "oldnew"); assert_eq!( resolver.resolve(name, &buffer, true), - (Bound(new_ns), LocalName(b"simple")) + (Bound(new_ns), LocalName("simple")) ); assert_eq!( resolver.resolve(name, &buffer, false), - (Unbound, LocalName(b"simple")) + (Unbound, LocalName("simple")) ); assert_eq!(resolver.find(name, &buffer), Bound(new_ns)); resolver.pop(&mut buffer); - assert_eq!(buffer, b"old"); + assert_eq!(buffer, "old"); assert_eq!( resolver.resolve(name, &buffer, true), - (Bound(old_ns), LocalName(b"simple")) + (Bound(old_ns), LocalName("simple")) ); assert_eq!( resolver.resolve(name, &buffer, false), - (Unbound, LocalName(b"simple")) + (Unbound, LocalName("simple")) ); assert_eq!(resolver.find(name, &buffer), Bound(old_ns)); } @@ -640,35 +640,35 @@ mod namespaces { /// See #[test] fn reset() { - let name = QName(b"simple"); - let old_ns = Namespace(b"old"); + let name = QName("simple"); + let old_ns = Namespace("old"); let mut resolver = NamespaceResolver::default(); - let mut buffer = Vec::new(); + let mut buffer = String::new(); resolver.push(&BytesStart::from_content(" xmlns='old'", 0), &mut buffer); resolver.push(&BytesStart::from_content(" xmlns=''", 0), &mut buffer); - assert_eq!(buffer, b"old"); + assert_eq!(buffer, "old"); assert_eq!( resolver.resolve(name, &buffer, true), - (Unbound, LocalName(b"simple")) + (Unbound, LocalName("simple")) ); assert_eq!( resolver.resolve(name, &buffer, false), - (Unbound, LocalName(b"simple")) + (Unbound, LocalName("simple")) ); assert_eq!(resolver.find(name, &buffer), Unbound); resolver.pop(&mut buffer); - assert_eq!(buffer, b"old"); + assert_eq!(buffer, "old"); assert_eq!( resolver.resolve(name, &buffer, true), - (Bound(old_ns), LocalName(b"simple")) + (Bound(old_ns), LocalName("simple")) ); assert_eq!( resolver.resolve(name, &buffer, false), - (Unbound, LocalName(b"simple")) + (Unbound, LocalName("simple")) ); assert_eq!(resolver.find(name, &buffer), Bound(old_ns)); } @@ -681,31 +681,31 @@ mod namespaces { /// Basic tests that checks that basic resolver functionality is working #[test] fn basic() { - let name = QName(b"p:with-declared-prefix"); - let ns = Namespace(b"default"); + let name = QName("p:with-declared-prefix"); + let ns = Namespace("default"); let mut resolver = NamespaceResolver::default(); - let mut buffer = Vec::new(); + let mut buffer = String::new(); resolver.push( &BytesStart::from_content(" xmlns:p='default'", 0), &mut buffer, ); - assert_eq!(buffer, b"pdefault"); + assert_eq!(buffer, "pdefault"); // Check that tags without namespaces does not change result resolver.push(&BytesStart::from_content("", 0), &mut buffer); - assert_eq!(buffer, b"pdefault"); + assert_eq!(buffer, "pdefault"); resolver.pop(&mut buffer); - assert_eq!(buffer, b"pdefault"); + assert_eq!(buffer, "pdefault"); assert_eq!( resolver.resolve(name, &buffer, true), - (Bound(ns), LocalName(b"with-declared-prefix")) + (Bound(ns), LocalName("with-declared-prefix")) ); assert_eq!( resolver.resolve(name, &buffer, false), - (Bound(ns), LocalName(b"with-declared-prefix")) + (Bound(ns), LocalName("with-declared-prefix")) ); assert_eq!(resolver.find(name, &buffer), Bound(ns)); } @@ -713,36 +713,36 @@ mod namespaces { /// Test adding a second level of namespaces, which replaces the previous binding #[test] fn override_namespace() { - let name = QName(b"p:with-declared-prefix"); - let old_ns = Namespace(b"old"); - let new_ns = Namespace(b"new"); + let name = QName("p:with-declared-prefix"); + let old_ns = Namespace("old"); + let new_ns = Namespace("new"); let mut resolver = NamespaceResolver::default(); - let mut buffer = Vec::new(); + let mut buffer = String::new(); resolver.push(&BytesStart::from_content(" xmlns:p='old'", 0), &mut buffer); resolver.push(&BytesStart::from_content(" xmlns:p='new'", 0), &mut buffer); - assert_eq!(buffer, b"poldpnew"); + assert_eq!(buffer, "poldpnew"); assert_eq!( resolver.resolve(name, &buffer, true), - (Bound(new_ns), LocalName(b"with-declared-prefix")) + (Bound(new_ns), LocalName("with-declared-prefix")) ); assert_eq!( resolver.resolve(name, &buffer, false), - (Bound(new_ns), LocalName(b"with-declared-prefix")) + (Bound(new_ns), LocalName("with-declared-prefix")) ); assert_eq!(resolver.find(name, &buffer), Bound(new_ns)); resolver.pop(&mut buffer); - assert_eq!(buffer, b"pold"); + assert_eq!(buffer, "pold"); assert_eq!( resolver.resolve(name, &buffer, true), - (Bound(old_ns), LocalName(b"with-declared-prefix")) + (Bound(old_ns), LocalName("with-declared-prefix")) ); assert_eq!( resolver.resolve(name, &buffer, false), - (Bound(old_ns), LocalName(b"with-declared-prefix")) + (Bound(old_ns), LocalName("with-declared-prefix")) ); assert_eq!(resolver.find(name, &buffer), Bound(old_ns)); } @@ -753,35 +753,35 @@ mod namespaces { /// See #[test] fn reset() { - let name = QName(b"p:with-declared-prefix"); - let old_ns = Namespace(b"old"); + let name = QName("p:with-declared-prefix"); + let old_ns = Namespace("old"); let mut resolver = NamespaceResolver::default(); - let mut buffer = Vec::new(); + let mut buffer = String::new(); resolver.push(&BytesStart::from_content(" xmlns:p='old'", 0), &mut buffer); resolver.push(&BytesStart::from_content(" xmlns:p=''", 0), &mut buffer); - assert_eq!(buffer, b"poldp"); + assert_eq!(buffer, "poldp"); assert_eq!( resolver.resolve(name, &buffer, true), - (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix")) + (Unknown("p".to_owned()), LocalName("with-declared-prefix")) ); assert_eq!( resolver.resolve(name, &buffer, false), - (Unknown(b"p".to_vec()), LocalName(b"with-declared-prefix")) + (Unknown("p".to_owned()), LocalName("with-declared-prefix")) ); - assert_eq!(resolver.find(name, &buffer), Unknown(b"p".to_vec())); + assert_eq!(resolver.find(name, &buffer), Unknown("p".to_owned())); resolver.pop(&mut buffer); - assert_eq!(buffer, b"pold"); + assert_eq!(buffer, "pold"); assert_eq!( resolver.resolve(name, &buffer, true), - (Bound(old_ns), LocalName(b"with-declared-prefix")) + (Bound(old_ns), LocalName("with-declared-prefix")) ); assert_eq!( resolver.resolve(name, &buffer, false), - (Bound(old_ns), LocalName(b"with-declared-prefix")) + (Bound(old_ns), LocalName("with-declared-prefix")) ); assert_eq!(resolver.find(name, &buffer), Bound(old_ns)); } @@ -789,47 +789,47 @@ mod namespaces { #[test] fn undeclared_prefix() { - let name = QName(b"unknown:prefix"); + let name = QName("unknown:prefix"); let resolver = NamespaceResolver::default(); - let buffer = Vec::new(); + let buffer = String::new(); - assert_eq!(buffer, b""); + assert_eq!(buffer, ""); assert_eq!( resolver.resolve(name, &buffer, true), - (Unknown(b"unknown".to_vec()), LocalName(b"prefix")) + (Unknown("unknown".to_owned()), LocalName("prefix")) ); assert_eq!( resolver.resolve(name, &buffer, false), - (Unknown(b"unknown".to_vec()), LocalName(b"prefix")) + (Unknown("unknown".to_owned()), LocalName("prefix")) ); - assert_eq!(resolver.find(name, &buffer), Unknown(b"unknown".to_vec())); + assert_eq!(resolver.find(name, &buffer), Unknown("unknown".to_owned())); } /// Checks how the QName is decomposed to a prefix and a local name #[test] fn prefix_and_local_name() { - let name = QName(b"foo:bus"); - assert_eq!(name.prefix(), Some(Prefix(b"foo"))); - assert_eq!(name.local_name(), LocalName(b"bus")); - assert_eq!(name.decompose(), (LocalName(b"bus"), Some(Prefix(b"foo")))); - - let name = QName(b"foo:"); - assert_eq!(name.prefix(), Some(Prefix(b"foo"))); - assert_eq!(name.local_name(), LocalName(b"")); - assert_eq!(name.decompose(), (LocalName(b""), Some(Prefix(b"foo")))); - - let name = QName(b":foo"); - assert_eq!(name.prefix(), Some(Prefix(b""))); - assert_eq!(name.local_name(), LocalName(b"foo")); - assert_eq!(name.decompose(), (LocalName(b"foo"), Some(Prefix(b"")))); - - let name = QName(b"foo:bus:baz"); - assert_eq!(name.prefix(), Some(Prefix(b"foo"))); - assert_eq!(name.local_name(), LocalName(b"bus:baz")); + let name = QName("foo:bus"); + assert_eq!(name.prefix(), Some(Prefix("foo"))); + assert_eq!(name.local_name(), LocalName("bus")); + assert_eq!(name.decompose(), (LocalName("bus"), Some(Prefix("foo")))); + + let name = QName("foo:"); + assert_eq!(name.prefix(), Some(Prefix("foo"))); + assert_eq!(name.local_name(), LocalName("")); + assert_eq!(name.decompose(), (LocalName(""), Some(Prefix("foo")))); + + let name = QName(":foo"); + assert_eq!(name.prefix(), Some(Prefix(""))); + assert_eq!(name.local_name(), LocalName("foo")); + assert_eq!(name.decompose(), (LocalName("foo"), Some(Prefix("")))); + + let name = QName("foo:bus:baz"); + assert_eq!(name.prefix(), Some(Prefix("foo"))); + assert_eq!(name.local_name(), LocalName("bus:baz")); assert_eq!( name.decompose(), - (LocalName(b"bus:baz"), Some(Prefix(b"foo"))) + (LocalName("bus:baz"), Some(Prefix("foo"))) ); } } diff --git a/src/reader/buffered_reader.rs b/src/reader/buffered_reader.rs index a864ac44..4e6d9f6d 100644 --- a/src/reader/buffered_reader.rs +++ b/src/reader/buffered_reader.rs @@ -161,7 +161,7 @@ impl Reader { depth -= 1; } Ok(Event::Eof) => { - let name = self.decoder().decode(end.as_ref()); + let name = self.decoder().decode(end.as_ref().as_bytes()); return Err(Error::UnexpectedEof(format!("", name))); } _ => (), diff --git a/src/reader/mod.rs b/src/reader/mod.rs index 0ef0a14e..5d0b8a40 100644 --- a/src/reader/mod.rs +++ b/src/reader/mod.rs @@ -264,10 +264,10 @@ impl EncodingRef { /// /// Ok(Event::Start(e)) => { /// match e.name().as_ref() { -/// b"tag1" => println!("attributes values: {:?}", +/// "tag1" => println!("attributes values: {:?}", /// e.attributes().map(|a| a.unwrap().value) /// .collect::>()), -/// b"tag2" => count += 1, +/// "tag2" => count += 1, /// _ => (), /// } /// } @@ -343,9 +343,9 @@ impl Reader { /// loop { /// match reader.read_event_into(&mut buf) { /// Ok(Event::Start(ref e)) => match e.name().as_ref() { - /// b"tag1" | b"tag2" => (), + /// "tag1" | "tag2" => (), /// tag => { - /// assert_eq!(b"tag3", tag); + /// assert_eq!("tag3", tag); /// assert_eq!((3, 22), into_line_and_column(reader)); /// break; /// } diff --git a/src/reader/ns_reader.rs b/src/reader/ns_reader.rs index fab7231e..20049a2f 100644 --- a/src/reader/ns_reader.rs +++ b/src/reader/ns_reader.rs @@ -22,7 +22,7 @@ pub struct NsReader { reader: Reader, /// Buffer that contains names of namespace prefixes (the part between `xmlns:` /// and an `=`) and namespace values. - buffer: Vec, + buffer: String, /// A buffer to manage namespaces ns_resolver: NamespaceResolver, /// We cannot pop data from the namespace stack until returned `Empty` or `End` @@ -48,7 +48,7 @@ impl NsReader { fn new(reader: Reader) -> Self { Self { reader, - buffer: Vec::new(), + buffer: String::new(), ns_resolver: NamespaceResolver::default(), pending_pop: false, } @@ -211,7 +211,7 @@ impl NsReader { /// match reader.read_event().unwrap() { /// Event::Empty(e) => assert_eq!( /// reader.resolve_element(e.name()), - /// (Bound(Namespace(b"root namespace")), QName(b"tag").into()) + /// (Bound(Namespace("root namespace")), QName("tag").into()) /// ), /// _ => unreachable!(), /// } @@ -276,13 +276,13 @@ impl NsReader { /// let one = iter.next().unwrap().unwrap(); /// assert_eq!( /// reader.resolve_attribute(one.key), - /// (Unbound, QName(b"one").into()) + /// (Unbound, QName("one").into()) /// ); /// /// let two = iter.next().unwrap().unwrap(); /// assert_eq!( /// reader.resolve_attribute(two.key), - /// (Bound(Namespace(b"other namespace")), QName(b"two").into()) + /// (Bound(Namespace("other namespace")), QName("two").into()) /// ); /// } /// _ => unreachable!(), @@ -332,8 +332,8 @@ impl NsReader { /// count += 1; /// let (ns, local) = reader.resolve_element(e.name()); /// match local.as_ref() { - /// b"tag1" => assert_eq!(ns, Bound(Namespace(b"www.xxxx"))), - /// b"tag2" => assert_eq!(ns, Bound(Namespace(b"www.yyyy"))), + /// "tag1" => assert_eq!(ns, Bound(Namespace("www.xxxx"))), + /// "tag2" => assert_eq!(ns, Bound(Namespace("www.yyyy"))), /// _ => unreachable!(), /// } /// } @@ -386,13 +386,13 @@ impl NsReader { /// let mut txt = Vec::new(); /// loop { /// match reader.read_resolved_event_into(&mut buf).unwrap() { - /// (Bound(Namespace(b"www.xxxx")), Event::Start(e)) => { + /// (Bound(Namespace("www.xxxx")), Event::Start(e)) => { /// count += 1; - /// assert_eq!(e.local_name(), QName(b"tag1").into()); + /// assert_eq!(e.local_name(), QName("tag1").into()); /// } - /// (Bound(Namespace(b"www.yyyy")), Event::Start(e)) => { + /// (Bound(Namespace("www.yyyy")), Event::Start(e)) => { /// count += 1; - /// assert_eq!(e.local_name(), QName(b"tag2").into()); + /// assert_eq!(e.local_name(), QName("tag2").into()); /// } /// (_, Event::Start(_)) => unreachable!(), /// @@ -481,7 +481,7 @@ impl NsReader { /// reader.trim_text(true); /// let mut buf = Vec::new(); /// - /// let ns = Namespace(b"namespace 1"); + /// let ns = Namespace("namespace 1"); /// let start = BytesStart::from_content(r#"outer xmlns="namespace 1""#, 5); /// let end = start.to_end().into_owned(); /// @@ -564,8 +564,8 @@ impl<'i> NsReader<&'i [u8]> { /// count += 1; /// let (ns, local) = reader.resolve_element(e.name()); /// match local.as_ref() { - /// b"tag1" => assert_eq!(ns, Bound(Namespace(b"www.xxxx"))), - /// b"tag2" => assert_eq!(ns, Bound(Namespace(b"www.yyyy"))), + /// "tag1" => assert_eq!(ns, Bound(Namespace("www.xxxx"))), + /// "tag2" => assert_eq!(ns, Bound(Namespace("www.yyyy"))), /// _ => unreachable!(), /// } /// } @@ -617,13 +617,13 @@ impl<'i> NsReader<&'i [u8]> { /// let mut txt = Vec::new(); /// loop { /// match reader.read_resolved_event().unwrap() { - /// (Bound(Namespace(b"www.xxxx")), Event::Start(e)) => { + /// (Bound(Namespace("www.xxxx")), Event::Start(e)) => { /// count += 1; - /// assert_eq!(e.local_name(), QName(b"tag1").into()); + /// assert_eq!(e.local_name(), QName("tag1").into()); /// } - /// (Bound(Namespace(b"www.yyyy")), Event::Start(e)) => { + /// (Bound(Namespace("www.yyyy")), Event::Start(e)) => { /// count += 1; - /// assert_eq!(e.local_name(), QName(b"tag2").into()); + /// assert_eq!(e.local_name(), QName("tag2").into()); /// } /// (_, Event::Start(_)) => unreachable!(), /// @@ -697,7 +697,7 @@ impl<'i> NsReader<&'i [u8]> { /// "#); /// reader.trim_text(true); /// - /// let ns = Namespace(b"namespace 1"); + /// let ns = Namespace("namespace 1"); /// let start = BytesStart::from_content(r#"outer xmlns="namespace 1""#, 5); /// let end = start.to_end().into_owned(); /// diff --git a/src/reader/slice_reader.rs b/src/reader/slice_reader.rs index b3c5ac63..674bb5ab 100644 --- a/src/reader/slice_reader.rs +++ b/src/reader/slice_reader.rs @@ -161,7 +161,7 @@ impl<'a> Reader<&'a [u8]> { depth -= 1; } Ok(Event::Eof) => { - let name = self.decoder().decode(end.as_ref()); + let name = self.decoder().decode(end.as_ref().as_bytes()); return Err(Error::UnexpectedEof(format!("", name))); } _ => (), diff --git a/src/writer.rs b/src/writer.rs index 07b3939d..baf30707 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -22,7 +22,7 @@ use std::io::Write; /// let mut writer = Writer::new(Cursor::new(Vec::new())); /// loop { /// match reader.read_event() { -/// Ok(Event::Start(e)) if e.name().as_ref() == b"this_tag" => { +/// Ok(Event::Start(e)) if e.name().as_ref() == "this_tag" => { /// /// // crates a new element ... alternatively we could reuse `e` by calling /// // `e.into_owned()` @@ -37,7 +37,7 @@ use std::io::Write; /// // writes the event to the writer /// assert!(writer.write_event(Event::Start(elem)).is_ok()); /// }, -/// Ok(Event::End(e)) if e.name().as_ref() == b"this_tag" => { +/// Ok(Event::End(e)) if e.name().as_ref() == "this_tag" => { /// assert!(writer.write_event(Event::End(BytesEnd::new("my_elem"))).is_ok()); /// }, /// Ok(Event::Eof) => break, diff --git a/tests/namespaces.rs b/tests/namespaces.rs index 41f594fd..ab7b67c3 100644 --- a/tests/namespaces.rs +++ b/tests/namespaces.rs @@ -22,7 +22,7 @@ fn namespace() { // match r.read_resolved_event() { - Ok((ns, Start(_))) => assert_eq!(ns, Bound(Namespace(b"www1"))), + Ok((ns, Start(_))) => assert_eq!(ns, Bound(Namespace("www1"))), e => panic!( "expecting inner start element with to resolve to 'www1', got {:?}", e @@ -35,7 +35,7 @@ fn namespace() { } // match r.read_resolved_event() { - Ok((ns, End(_))) => assert_eq!(ns, Bound(Namespace(b"www1"))), + Ok((ns, End(_))) => assert_eq!(ns, Bound(Namespace("www1"))), e => panic!( "expecting inner end element with to resolve to 'www1', got {:?}", e @@ -65,7 +65,7 @@ fn default_namespace() { // match r.read_resolved_event() { - Ok((ns, Start(_))) => assert_eq!(ns, Bound(Namespace(b"www1"))), + Ok((ns, Start(_))) => assert_eq!(ns, Bound(Namespace("www1"))), e => panic!( "expecting inner start element with to resolve to 'www1', got {:?}", e @@ -73,7 +73,7 @@ fn default_namespace() { } // match r.read_resolved_event() { - Ok((ns, End(_))) => assert_eq!(ns, Bound(Namespace(b"www1"))), + Ok((ns, End(_))) => assert_eq!(ns, Bound(Namespace("www1"))), e => panic!( "expecting inner end element with to resolve to 'www1', got {:?}", e @@ -95,7 +95,7 @@ fn default_namespace_reset() { // match r.read_resolved_event() { - Ok((ns, Start(_))) => assert_eq!(ns, Bound(Namespace(b"www1"))), + Ok((ns, Start(_))) => assert_eq!(ns, Bound(Namespace("www1"))), e => panic!( "expecting outer start element with to resolve to 'www1', got {:?}", e @@ -118,7 +118,7 @@ fn default_namespace_reset() { // match r.read_resolved_event() { - Ok((ns, End(_))) => assert_eq!(ns, Bound(Namespace(b"www1"))), + Ok((ns, End(_))) => assert_eq!(ns, Bound(Namespace("www1"))), e => panic!( "expecting outer end element with to resolve to 'www1', got {:?}", e @@ -152,13 +152,13 @@ fn attributes_empty_ns() { }); assert_eq!( attrs.next(), - Some((Unbound, &b"att1"[..], Cow::Borrowed(&b"a"[..]))) + Some((Unbound, &"att1"[..], Cow::Borrowed(&b"a"[..]))) ); assert_eq!( attrs.next(), Some(( - Bound(Namespace(b"urn:example:r")), - &b"att2"[..], + Bound(Namespace("urn:example:r")), + &"att2"[..], Cow::Borrowed(&b"b"[..]) )) ); @@ -191,13 +191,13 @@ fn attributes_empty_ns_expanded() { }); assert_eq!( attrs.next(), - Some((Unbound, &b"att1"[..], Cow::Borrowed(&b"a"[..]))) + Some((Unbound, &"att1"[..], Cow::Borrowed(&b"a"[..]))) ); assert_eq!( attrs.next(), Some(( - Bound(Namespace(b"urn:example:r")), - &b"att2"[..], + Bound(Namespace("urn:example:r")), + &"att2"[..], Cow::Borrowed(&b"b"[..]) )) ); @@ -205,7 +205,7 @@ fn attributes_empty_ns_expanded() { } match r.read_resolved_event() { - Ok((Unbound, End(e))) => assert_eq!(e.name(), QName(b"a")), + Ok((Unbound, End(e))) => assert_eq!(e.name(), QName("a")), e => panic!("Expecting End event, got {:?}", e), } } @@ -221,8 +221,8 @@ fn default_ns_shadowing_empty() { { match r.read_resolved_event() { Ok((ns, Start(e))) => { - assert_eq!(ns, Bound(Namespace(b"urn:example:o"))); - assert_eq!(e.name(), QName(b"e")); + assert_eq!(ns, Bound(Namespace("urn:example:o"))); + assert_eq!(e.name(), QName("e")); } e => panic!("Expected Start event (), got {:?}", e), } @@ -232,8 +232,8 @@ fn default_ns_shadowing_empty() { { let e = match r.read_resolved_event() { Ok((ns, Empty(e))) => { - assert_eq!(ns, Bound(Namespace(b"urn:example:i"))); - assert_eq!(e.name(), QName(b"e")); + assert_eq!(ns, Bound(Namespace("urn:example:i"))); + assert_eq!(e.name(), QName("e")); e } e => panic!("Expecting Empty event, got {:?}", e), @@ -252,7 +252,7 @@ fn default_ns_shadowing_empty() { // apply to attributes. assert_eq!( attrs.next(), - Some((Unbound, &b"att1"[..], Cow::Borrowed(&b"a"[..]))) + Some((Unbound, &"att1"[..], Cow::Borrowed(&b"a"[..]))) ); assert_eq!(attrs.next(), None); } @@ -260,8 +260,8 @@ fn default_ns_shadowing_empty() { // match r.read_resolved_event() { Ok((ns, End(e))) => { - assert_eq!(ns, Bound(Namespace(b"urn:example:o"))); - assert_eq!(e.name(), QName(b"e")); + assert_eq!(ns, Bound(Namespace("urn:example:o"))); + assert_eq!(e.name(), QName("e")); } e => panic!("Expected End event (), got {:?}", e), } @@ -278,8 +278,8 @@ fn default_ns_shadowing_expanded() { { match r.read_resolved_event() { Ok((ns, Start(e))) => { - assert_eq!(ns, Bound(Namespace(b"urn:example:o"))); - assert_eq!(e.name(), QName(b"e")); + assert_eq!(ns, Bound(Namespace("urn:example:o"))); + assert_eq!(e.name(), QName("e")); } e => panic!("Expected Start event (), got {:?}", e), } @@ -289,8 +289,8 @@ fn default_ns_shadowing_expanded() { { let e = match r.read_resolved_event() { Ok((ns, Start(e))) => { - assert_eq!(ns, Bound(Namespace(b"urn:example:i"))); - assert_eq!(e.name(), QName(b"e")); + assert_eq!(ns, Bound(Namespace("urn:example:i"))); + assert_eq!(e.name(), QName("e")); e } e => panic!("Expecting Start event (), got {:?}", e), @@ -308,7 +308,7 @@ fn default_ns_shadowing_expanded() { // apply to attributes. assert_eq!( attrs.next(), - Some((Unbound, &b"att1"[..], Cow::Borrowed(&b"a"[..]))) + Some((Unbound, &"att1"[..], Cow::Borrowed(&b"a"[..]))) ); assert_eq!(attrs.next(), None); } @@ -316,16 +316,16 @@ fn default_ns_shadowing_expanded() { // virtual match r.read_resolved_event() { Ok((ns, End(e))) => { - assert_eq!(ns, Bound(Namespace(b"urn:example:i"))); - assert_eq!(e.name(), QName(b"e")); + assert_eq!(ns, Bound(Namespace("urn:example:i"))); + assert_eq!(e.name(), QName("e")); } e => panic!("Expected End event (), got {:?}", e), } // match r.read_resolved_event() { Ok((ns, End(e))) => { - assert_eq!(ns, Bound(Namespace(b"urn:example:o"))); - assert_eq!(e.name(), QName(b"e")); + assert_eq!(ns, Bound(Namespace("urn:example:o"))); + assert_eq!(e.name(), QName("e")); } e => panic!("Expected End event (), got {:?}", e), } @@ -347,7 +347,7 @@ fn reserved_name() { // match r.read_resolved_event() { - Ok((ns, Empty(_))) => assert_eq!(ns, Bound(Namespace(b"www1"))), + Ok((ns, Empty(_))) => assert_eq!(ns, Bound(Namespace("www1"))), e => panic!( "Expected empty element bound to namespace 'www1', got {:?}", e diff --git a/tests/serde-de.rs b/tests/serde-de.rs index 1b6deebc..92313eb7 100644 --- a/tests/serde-de.rs +++ b/tests/serde-de.rs @@ -236,7 +236,7 @@ mod trivial { match from_str::>(&format!("{}", $value)) { // Expected unexpected start element `` - Err(DeError::UnexpectedStart(tag)) => assert_eq!(tag, b"root"), + Err(DeError::UnexpectedStart(tag)) => assert_eq!(tag, "root"), x => panic!( r#"Expected `Err(DeError::UnexpectedStart("root"))`, but got `{:?}`"#, x diff --git a/tests/test.rs b/tests/test.rs index 0a4d0664..777c11ca 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -34,14 +34,14 @@ fn test_attributes_empty() { assert_eq!( attrs.next(), Some(Ok(Attribute { - key: QName(b"att1"), + key: QName("att1"), value: Cow::Borrowed(b"a"), })) ); assert_eq!( attrs.next(), Some(Ok(Attribute { - key: QName(b"att2"), + key: QName("att2"), value: Cow::Borrowed(b"b"), })) ); @@ -62,7 +62,7 @@ fn test_attribute_equal() { assert_eq!( attrs.next(), Some(Ok(Attribute { - key: QName(b"att1"), + key: QName("att1"), value: Cow::Borrowed(b"a=b"), })) ); @@ -898,16 +898,16 @@ fn test_issue299() -> Result<(), Error> { match reader.read_event()? { Start(e) | Empty(e) => { let attr_count = match e.name().as_ref() { - b"MICEX_DOC" => 1, - b"SECURITY" => 4, - b"RECORDS" => 26, + "MICEX_DOC" => 1, + "SECURITY" => 4, + "RECORDS" => 26, _ => unreachable!(), }; assert_eq!( attr_count, e.attributes().filter(Result::is_ok).count(), "mismatch att count on '{:?}'", - reader.decoder().decode(e.name().as_ref()) + e.name().as_ref() ); } Eof => break, diff --git a/tests/unit_tests.rs b/tests/unit_tests.rs index 7365778b..412a1a5d 100644 --- a/tests/unit_tests.rs +++ b/tests/unit_tests.rs @@ -13,7 +13,7 @@ use pretty_assertions::assert_eq; macro_rules! next_eq_name { ($r:expr, $t:tt, $bytes:expr) => { match $r.read_event().unwrap() { - $t(ref e) if e.name().as_ref() == $bytes => (), + $t(ref e) if e.name().as_ref().as_bytes() == $bytes => (), e => panic!( "expecting {}({:?}), found {:?}", stringify!($t), @@ -601,14 +601,14 @@ fn test_closing_bracket_in_single_quote_attr() { assert_eq!( attrs.next(), Some(Ok(Attribute { - key: QName(b"attr"), + key: QName("attr"), value: Cow::Borrowed(b">"), })) ); assert_eq!( attrs.next(), Some(Ok(Attribute { - key: QName(b"check"), + key: QName("check"), value: Cow::Borrowed(b"2"), })) ); @@ -629,14 +629,14 @@ fn test_closing_bracket_in_double_quote_attr() { assert_eq!( attrs.next(), Some(Ok(Attribute { - key: QName(b"attr"), + key: QName("attr"), value: Cow::Borrowed(b">"), })) ); assert_eq!( attrs.next(), Some(Ok(Attribute { - key: QName(b"check"), + key: QName("check"), value: Cow::Borrowed(b"2"), })) ); @@ -657,14 +657,14 @@ fn test_closing_bracket_in_double_quote_mixed() { assert_eq!( attrs.next(), Some(Ok(Attribute { - key: QName(b"attr"), + key: QName("attr"), value: Cow::Borrowed(b"'>'"), })) ); assert_eq!( attrs.next(), Some(Ok(Attribute { - key: QName(b"check"), + key: QName("check"), value: Cow::Borrowed(b"'2'"), })) ); @@ -685,14 +685,14 @@ fn test_closing_bracket_in_single_quote_mixed() { assert_eq!( attrs.next(), Some(Ok(Attribute { - key: QName(b"attr"), + key: QName("attr"), value: Cow::Borrowed(br#"">""#), })) ); assert_eq!( attrs.next(), Some(Ok(Attribute { - key: QName(b"check"), + key: QName("check"), value: Cow::Borrowed(br#""2""#), })) ); diff --git a/tests/xmlrs_reader_tests.rs b/tests/xmlrs_reader_tests.rs index 5a7120b8..437ee449 100644 --- a/tests/xmlrs_reader_tests.rs +++ b/tests/xmlrs_reader_tests.rs @@ -389,7 +389,7 @@ fn test_bytes(input: &[u8], output: &[u8], trim: bool) { } Ok((_, Event::DocType(e))) => format!("DocType({})", decoder.decode(&e).unwrap()), Ok((n, Event::Start(e))) => { - let name = namespace_name(n, e.name(), decoder); + let name = namespace_name(n, e.name()); match make_attrs(&e, decoder) { Ok(attrs) if attrs.is_empty() => format!("StartElement({})", &name), Ok(attrs) => format!("StartElement({} [{}])", &name, &attrs), @@ -397,7 +397,7 @@ fn test_bytes(input: &[u8], output: &[u8], trim: bool) { } } Ok((n, Event::Empty(e))) => { - let name = namespace_name(n, e.name(), decoder); + let name = namespace_name(n, e.name()); match make_attrs(&e, decoder) { Ok(attrs) if attrs.is_empty() => format!("EmptyElement({})", &name), Ok(attrs) => format!("EmptyElement({} [{}])", &name, &attrs), @@ -405,7 +405,7 @@ fn test_bytes(input: &[u8], output: &[u8], trim: bool) { } } Ok((n, Event::End(e))) => { - let name = namespace_name(n, e.name(), decoder); + let name = namespace_name(n, e.name()); format!("EndElement({})", name) } Ok((_, Event::Comment(e))) => format!("Comment({})", decoder.decode(&e).unwrap()), @@ -441,12 +441,11 @@ fn test_bytes(input: &[u8], output: &[u8], trim: bool) { } } -fn namespace_name(n: ResolveResult, name: QName, decoder: Decoder) -> String { - let name = decoder.decode(name.as_ref()).unwrap(); +fn namespace_name(n: ResolveResult, name: QName) -> String { match n { // Produces string '{namespace}prefixed_name' - ResolveResult::Bound(n) => format!("{{{}}}{}", decoder.decode(n.as_ref()).unwrap(), name), - _ => name.to_string(), + ResolveResult::Bound(n) => format!("{{{}}}{}", n.as_ref(), name.as_ref()), + _ => name.as_ref().to_string(), } } @@ -456,7 +455,7 @@ fn make_attrs(e: &BytesStart, decoder: Decoder) -> ::std::result::Result { if a.key.as_namespace_binding().is_none() { - let key = decoder.decode(a.key.as_ref()).unwrap(); + let key = a.key.as_ref(); let value = decoder.decode(a.value.as_ref()).unwrap(); let unescaped_value = unescape(&value).unwrap(); atts.push(format!(