Skip to content
4 changes: 4 additions & 0 deletions benches/macrobenches.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// std::hint::black_box stable since 1.66, but our MSRV = 1.56.
// criterion::black_box is deprecated in since criterion 0.7.
// Running benchmarks assumed on current Rust version, so this should be fine
#![allow(clippy::incompatible_msrv)]
use criterion::{self, criterion_group, criterion_main, Criterion, Throughput};
use quick_xml::events::Event;
use quick_xml::reader::{NsReader, Reader};
Expand Down
4 changes: 4 additions & 0 deletions benches/microbenches.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// std::hint::black_box stable since 1.66, but our MSRV = 1.56.
// criterion::black_box is deprecated in since criterion 0.7.
// Running benchmarks assumed on current Rust version, so this should be fine
#![allow(clippy::incompatible_msrv)]
use criterion::{self, criterion_group, criterion_main, Criterion};
use pretty_assertions::assert_eq;
use quick_xml::escape::{escape, unescape};
Expand Down
2 changes: 1 addition & 1 deletion examples/flattened_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ fn main() {
</model>
"#;

let model: Model = from_str(&x).unwrap();
let model: Model = from_str(x).unwrap();
println!("{:?}", model);
// Model { elem: [Foo(Foo { a: "1", subfoo: SubFoo { a1: "2", a2: "42", a3: "1337" } }), Bar(Bar { b: "22" })] }

Expand Down
2 changes: 1 addition & 1 deletion src/de/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl<'i, 'd> QNameDeserializer<'i, 'd> {
// can apper only in this literal form, as `xml` prefix cannot be redeclared or unbound
let (local, prefix_opt) = name.decompose();
if prefix_opt.map_or(false, |prefix| prefix.is_xml()) {
decoder.decode_into(&name.into_inner(), key_buf)?;
decoder.decode_into(name.into_inner(), key_buf)?;
} else {
decoder.decode_into(local.into_inner(), key_buf)?;
}
Expand Down
10 changes: 5 additions & 5 deletions src/de/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,16 +207,16 @@ where
de: &'d mut Deserializer<'de, R, E>,
start: BytesStart<'de>,
fields: &'static [&'static str],
) -> Result<Self, DeError> {
Ok(Self {
) -> Self {
Self {
de,
iter: IterState::new(start.name().as_ref().len(), false),
start,
source: ValueSource::Unknown,
fields,
has_value_field: fields.contains(&VALUE_KEY),
has_text_field: fields.contains(&TEXT_KEY),
})
}
}

/// Determines if subtree started with the specified event shoould be skipped.
Expand Down Expand Up @@ -801,7 +801,7 @@ where
V: Visitor<'de>,
{
match self.map.de.next()? {
DeEvent::Start(e) => visitor.visit_map(ElementMapAccess::new(self.map.de, e, fields)?),
DeEvent::Start(e) => visitor.visit_map(ElementMapAccess::new(self.map.de, e, fields)),
DeEvent::Text(e) => {
SimpleTypeDeserializer::from_text_content(e).deserialize_struct("", fields, visitor)
}
Expand Down Expand Up @@ -1144,7 +1144,7 @@ where
where
V: Visitor<'de>,
{
visitor.visit_map(ElementMapAccess::new(self.de, self.start, fields)?)
visitor.visit_map(ElementMapAccess::new(self.de, self.start, fields))
}

fn deserialize_enum<V>(
Expand Down
57 changes: 29 additions & 28 deletions src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2815,34 +2815,31 @@ where
fn skip(&mut self) -> Result<(), DeError> {
let event = self.next()?;
self.skip_event(event)?;
match self.write.back() {
// Skip all subtree, if we skip a start event
Some(DeEvent::Start(e)) => {
let end = e.name().as_ref().to_owned();
let mut depth = 0;
loop {
let event = self.next()?;
match event {
DeEvent::Start(ref e) if e.name().as_ref() == end => {
self.skip_event(event)?;
depth += 1;
}
DeEvent::End(ref e) if e.name().as_ref() == end => {
self.skip_event(event)?;
if depth == 0 {
break;
}
depth -= 1;
}
DeEvent::Eof => {
self.skip_event(event)?;
// Skip all subtree, if we skip a start event
if let Some(DeEvent::Start(e)) = self.write.back() {
let end = e.name().as_ref().to_owned();
let mut depth = 0;
loop {
let event = self.next()?;
match event {
DeEvent::Start(ref e) if e.name().as_ref() == end => {
self.skip_event(event)?;
depth += 1;
}
DeEvent::End(ref e) if e.name().as_ref() == end => {
self.skip_event(event)?;
if depth == 0 {
break;
}
_ => self.skip_event(event)?,
depth -= 1;
}
DeEvent::Eof => {
self.skip_event(event)?;
break;
}
_ => self.skip_event(event)?,
}
}
_ => (),
}
Ok(())
}
Expand Down Expand Up @@ -3214,7 +3211,7 @@ where
}
}

impl<'de, 'a, R, E> de::Deserializer<'de> for &'a mut Deserializer<'de, R, E>
impl<'de, R, E> de::Deserializer<'de> for &mut Deserializer<'de, R, E>
where
R: XmlRead<'de>,
E: EntityResolver,
Expand All @@ -3235,7 +3232,7 @@ where
// When document is pretty-printed there could be whitespaces before the root element
self.skip_whitespaces()?;
match self.next()? {
DeEvent::Start(e) => visitor.visit_map(ElementMapAccess::new(self, e, fields)?),
DeEvent::Start(e) => visitor.visit_map(ElementMapAccess::new(self, e, fields)),
// SAFETY: The reader is guaranteed that we don't have unmatched tags
// If we here, then our deserializer has a bug
DeEvent::End(e) => unreachable!("{:?}", e),
Expand Down Expand Up @@ -3330,7 +3327,7 @@ where
DeEvent::Text(t) if t.is_empty() => visitor.visit_none(),
DeEvent::Eof => visitor.visit_none(),
// if the `xsi:nil` attribute is set to true we got a none value
DeEvent::Start(start) if self.reader.reader.has_nil_attr(&start) => {
DeEvent::Start(start) if self.reader.reader.has_nil_attr(start) => {
self.skip_next_tree()?;
visitor.visit_none()
}
Expand All @@ -3354,7 +3351,7 @@ where
///
/// Technically, multiple top-level elements violates XML rule of only one top-level
/// element, but we consider this as several concatenated XML documents.
impl<'de, 'a, R, E> SeqAccess<'de> for &'a mut Deserializer<'de, R, E>
impl<'de, R, E> SeqAccess<'de> for &mut Deserializer<'de, R, E>
where
R: XmlRead<'de>,
E: EntityResolver,
Expand All @@ -3381,7 +3378,7 @@ where
}
}

impl<'de, 'a, R, E> IntoDeserializer<'de, DeError> for &'a mut Deserializer<'de, R, E>
impl<'de, R, E> IntoDeserializer<'de, DeError> for &mut Deserializer<'de, R, E>
where
R: XmlRead<'de>,
E: EntityResolver,
Expand Down Expand Up @@ -4508,6 +4505,8 @@ mod tests {
use super::*;

/// <tag1><tag2>...
// The same name is intentional
#[allow(clippy::module_inception)]
mod start {
use super::*;
use pretty_assertions::assert_eq;
Expand Down Expand Up @@ -4980,6 +4979,8 @@ mod tests {
}
}

// The same name is intentional
#[allow(clippy::module_inception)]
mod cdata {
use super::*;
use pretty_assertions::assert_eq;
Expand Down
2 changes: 1 addition & 1 deletion src/de/var.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ where
V: Visitor<'de>,
{
match self.de.next()? {
DeEvent::Start(e) => visitor.visit_map(ElementMapAccess::new(self.de, e, fields)?),
DeEvent::Start(e) => visitor.visit_map(ElementMapAccess::new(self.de, e, fields)),
DeEvent::Text(e) => {
SimpleTypeDeserializer::from_text_content(e).deserialize_struct("", fields, visitor)
}
Expand Down
2 changes: 2 additions & 0 deletions src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@ pub fn decode_into(
/// |`3C 3F 78 6D`|UTF-8, ISO 646, ASCII, some part of ISO 8859, Shift-JIS, EUC, or any other 7-bit, 8-bit, or mixed-width encoding which ensures that the characters of ASCII have their normal positions, width, and values; the actual encoding declaration must be read to detect which of these applies, but since all of these encodings use the same bit patterns for the relevant ASCII characters, the encoding declaration itself may be read reliably
#[cfg(feature = "encoding")]
pub fn detect_encoding(bytes: &[u8]) -> Option<(&'static Encoding, usize)> {
// Prevent suggesting "<?xm". We want to have the same formatted lines for all arms.
#[allow(clippy::byte_char_slices)]
match bytes {
// with BOM
_ if bytes.starts_with(UTF16_BE_BOM) => Some((UTF_16BE, 2)),
Expand Down
3 changes: 2 additions & 1 deletion src/escape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2183,7 +2183,8 @@ mod normalization {
if ch == '\u{0085}' {
assert_eq!(normalize_xml11_eols(input), "\n", "{}", description);
} else {
let mut expected = utf8.clone();
// utf8 is copied, because [u8; 3] implements Copy
let mut expected = utf8;
expected[0] = b'\n';
let expected = std::str::from_utf8(&expected).expect(&description);
assert_eq!(normalize_xml11_eols(input), expected, "{}", description);
Expand Down
2 changes: 1 addition & 1 deletion src/events/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ impl<'a> Attributes<'a> {
impl<'a> Debug for Attributes<'a> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_struct("Attributes")
.field("bytes", &Bytes(&self.bytes))
.field("bytes", &Bytes(self.bytes))
.field("state", &self.state)
.field("decoder", &self.decoder)
.finish()
Expand Down
16 changes: 8 additions & 8 deletions src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,12 +358,12 @@ impl<'a> arbitrary::Arbitrary<'a> for BytesStart<'a> {
return Err(arbitrary::Error::IncorrectFormat);
}
let mut result = Self::new(s);
result.extend_attributes(Vec::<(&str, &str)>::arbitrary(u)?.into_iter());
result.extend_attributes(Vec::<(&str, &str)>::arbitrary(u)?);
Ok(result)
}

fn size_hint(depth: usize) -> (usize, Option<usize>) {
return <&str as arbitrary::Arbitrary>::size_hint(depth);
<&str as arbitrary::Arbitrary>::size_hint(depth)
}
}

Expand Down Expand Up @@ -483,7 +483,7 @@ impl<'a> arbitrary::Arbitrary<'a> for BytesEnd<'a> {
Ok(Self::new(<&str>::arbitrary(u)?))
}
fn size_hint(depth: usize) -> (usize, Option<usize>) {
return <&str as arbitrary::Arbitrary>::size_hint(depth);
<&str as arbitrary::Arbitrary>::size_hint(depth)
}
}

Expand Down Expand Up @@ -692,7 +692,7 @@ impl<'a> arbitrary::Arbitrary<'a> for BytesText<'a> {
}

fn size_hint(depth: usize) -> (usize, Option<usize>) {
return <&str as arbitrary::Arbitrary>::size_hint(depth);
<&str as arbitrary::Arbitrary>::size_hint(depth)
}
}

Expand Down Expand Up @@ -976,7 +976,7 @@ impl<'a> arbitrary::Arbitrary<'a> for BytesCData<'a> {
Ok(Self::new(<&str>::arbitrary(u)?))
}
fn size_hint(depth: usize) -> (usize, Option<usize>) {
return <&str as arbitrary::Arbitrary>::size_hint(depth);
<&str as arbitrary::Arbitrary>::size_hint(depth)
}
}

Expand Down Expand Up @@ -1062,7 +1062,7 @@ impl<'a> BytesPI<'a> {
#[inline]
pub fn into_owned(self) -> BytesPI<'static> {
BytesPI {
content: self.content.into_owned().into(),
content: self.content.into_owned(),
}
}

Expand Down Expand Up @@ -1171,7 +1171,7 @@ impl<'a> arbitrary::Arbitrary<'a> for BytesPI<'a> {
Ok(Self::new(<&str>::arbitrary(u)?))
}
fn size_hint(depth: usize) -> (usize, Option<usize>) {
return <&str as arbitrary::Arbitrary>::size_hint(depth);
<&str as arbitrary::Arbitrary>::size_hint(depth)
}
}

Expand Down Expand Up @@ -1456,7 +1456,7 @@ impl<'a> arbitrary::Arbitrary<'a> for BytesDecl<'a> {
}

fn size_hint(depth: usize) -> (usize, Option<usize>) {
return <&str as arbitrary::Arbitrary>::size_hint(depth);
<&str as arbitrary::Arbitrary>::size_hint(depth)
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
// Enable feature requirements in the docs from 1.57
// See https://stackoverflow.com/questions/61417452
// docs.rs defines `docsrs` when building documentation
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
// Since 1.92 `doc_auto_cfg` was merged into `doc_cfg`
#![cfg_attr(docsrs, feature(doc_cfg))]

#[cfg(feature = "serialize")]
pub mod de;
Expand Down
9 changes: 4 additions & 5 deletions src/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ impl NamespaceResolver {
match prefix {
PrefixDeclaration::Default => {
let start = self.buffer.len();
self.buffer.extend_from_slice(&namespace.0);
self.buffer.extend_from_slice(namespace.0);
self.bindings.push(NamespaceBinding {
start,
prefix_len: 0,
Expand Down Expand Up @@ -640,7 +640,7 @@ impl NamespaceResolver {

let start = self.buffer.len();
self.buffer.extend_from_slice(prefix);
self.buffer.extend_from_slice(&namespace.0);
self.buffer.extend_from_slice(namespace.0);
self.bindings.push(NamespaceBinding {
start,
prefix_len: prefix.len(),
Expand All @@ -662,9 +662,8 @@ impl NamespaceResolver {
// (default namespace) attribute.
for a in start.attributes().with_checks(false) {
if let Ok(Attribute { key: k, value: v }) = a {
match k.as_namespace_binding() {
Some(prefix) => self.add(prefix, Namespace(&v))?,
None => {}
if let Some(prefix) = k.as_namespace_binding() {
self.add(prefix, Namespace(&v))?;
}
} else {
break;
Expand Down
4 changes: 2 additions & 2 deletions src/reader/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ impl ReaderState {
// We want report error at place where name is expected - this is just
// before `>`
self.last_error_offset = self.offset - 1;
return Err(Error::IllFormed(IllFormedError::MissingDoctypeName));
Err(Error::IllFormed(IllFormedError::MissingDoctypeName))
}
}
}
Expand Down Expand Up @@ -239,7 +239,7 @@ impl ReaderState {
///
/// Returns `Decl` or `PI` event
pub fn emit_question_mark<'b>(&mut self, buf: &'b [u8]) -> Result<Event<'b>> {
debug_assert!(buf.len() > 0);
debug_assert!(!buf.is_empty());
debug_assert_eq!(buf[0], b'?');

let len = buf.len();
Expand Down
2 changes: 1 addition & 1 deletion src/se/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ impl<'w, 'k, W: Write> SerializeMap for Map<'w, 'k, W> {
where
T: ?Sized + Serialize,
{
if let Some(_) = self.key.take() {
if self.key.take().is_some() {
return Err(SeError::Custom(
"calling `serialize_key` twice without `serialize_value`".to_string(),
));
Expand Down
6 changes: 4 additions & 2 deletions src/se/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,8 @@ macro_rules! forward {
///
/// <https://www.w3.org/TR/xml11/#NT-NameStartChar>
const fn is_xml11_name_start_char(ch: char) -> bool {
// Not need to use macro when core primitives is enough
#[allow(clippy::match_like_matches_macro)]
match ch {
':'
| 'A'..='Z'
Expand Down Expand Up @@ -467,7 +469,7 @@ const fn is_xml11_name_char(ch: char) -> bool {

/// Helper struct to self-defense from errors
#[derive(Clone, Copy, Debug, PartialEq)]
pub(self) struct XmlName<'n>(&'n str);
struct XmlName<'n>(&'n str);

impl<'n> XmlName<'n> {
/// Checks correctness of the XML name according to [XML 1.1 specification]
Expand Down Expand Up @@ -638,7 +640,7 @@ impl<'w, 'r, W: Write> Serializer<'w, 'r, W> {
allow_primitive: true,
expand_empty_elements: false,
},
root_tag: root_tag.map(|tag| XmlName::try_from(tag)).transpose()?,
root_tag: root_tag.map(XmlName::try_from).transpose()?,
})
}

Expand Down
2 changes: 1 addition & 1 deletion src/se/simple_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ where
if let Some(part) = it.next() {
writer.write_str(part)?;
}
while let Some(part) = it.next() {
for part in it {
writer.write_str("]]><![CDATA[")?;
writer.write_str(part)?;
}
Expand Down
Loading