Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade quick-xml #67

Merged
merged 2 commits into from Dec 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,7 @@
- Wrap `quick_xml::XmlError` into a newtype [`#65`](https://github.com/rust-syndication/atom/pull/65)
- Implement `std::error::Error` for `XmlError`. Mark helper traits as `pub(crate)` to prevent their accidental leakage to public API [`#66`](https://github.com/rust-syndication/atom/pull/66)
- Bump MSRV (Minimum Supported Rust Version) from 1.40.0 to 1.54.0 [`#66`](https://github.com/rust-syndication/atom/pull/66) and [`#69`](https://github.com/rust-syndication/atom/pull/69)
- Upgrade `quick_xml` to `0.27` and `derive_builder` to `0.12` [`#67`](https://github.com/rust-syndication/atom/pull/67)

## 0.11.0 - 2021-10-20

Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Expand Up @@ -13,8 +13,8 @@ categories = ["parser-implementations"]
include = ["src/*", "Cargo.toml", "LICENSE-MIT", "LICENSE-APACHE", "README.md"]

[dependencies]
quick-xml = { version = "0.22", features = ["encoding"] }
derive_builder = { version = "0.10.2", optional = true }
quick-xml = { version = "0.27", features = ["encoding"] }
derive_builder = { version = "0.12", optional = true }
never = { version = "0.1", optional = true }
serde = { version = "1.0", optional = true, features = ["derive"] }
chrono = { version = "0.4", default-features = false, features = ["alloc"] }
Expand Down
42 changes: 14 additions & 28 deletions src/category.rs
@@ -1,13 +1,13 @@
use std::borrow::Cow;
use std::io::{BufRead, Write};

use quick_xml::events::attributes::Attributes;
use quick_xml::events::{BytesStart, Event};
use quick_xml::Reader;
use quick_xml::Writer;

use crate::error::{Error, XmlError};
use crate::fromxml::FromXml;
use crate::toxml::ToXml;
use crate::util::{attr_value, decode};

/// Represents a category in an Atom feed
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
Expand Down Expand Up @@ -129,48 +129,34 @@ impl Category {
}
}

impl FromXml for Category {
fn from_xml<B: BufRead>(
impl Category {
pub(crate) fn from_xml<'s, B: BufRead>(
reader: &mut Reader<B>,
mut atts: Attributes<'_>,
element: &'s BytesStart<'s>,
) -> Result<Self, Error> {
let mut category = Category::default();

for att in atts.with_checks(false).flatten() {
match att.key {
b"term" => {
category.term = att
.unescape_and_decode_value(reader)
.map_err(XmlError::new)?
for att in element.attributes().with_checks(false).flatten() {
match decode(att.key.as_ref(), reader)? {
Cow::Borrowed("term") => {
category.term = attr_value(&att, reader)?.to_string();
}
b"scheme" => {
category.scheme = Some(
att.unescape_and_decode_value(reader)
.map_err(XmlError::new)?,
)
Cow::Borrowed("scheme") => {
category.scheme = Some(attr_value(&att, reader)?.to_string());
}
b"label" => {
category.label = Some(
att.unescape_and_decode_value(reader)
.map_err(XmlError::new)?,
)
Cow::Borrowed("label") => {
category.label = Some(attr_value(&att, reader)?.to_string());
}
_ => {}
}
}

reader
.read_to_end(b"category", &mut Vec::new())
.map_err(XmlError::new)?;

Ok(category)
}
}

impl ToXml for Category {
fn to_xml<W: Write>(&self, writer: &mut Writer<W>) -> Result<(), XmlError> {
let name = b"category";
let mut element = BytesStart::borrowed(name, name.len());
let mut element = BytesStart::new("category");
element.push_attribute(("term", &*self.term));

if let Some(ref scheme) = self.scheme {
Expand Down
48 changes: 19 additions & 29 deletions src/content.rs
@@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::io::{BufRead, Write};

use quick_xml::events::attributes::Attributes;
Expand All @@ -8,7 +9,7 @@ use quick_xml::Writer;
use crate::error::{Error, XmlError};
use crate::fromxml::FromXml;
use crate::toxml::ToXml;
use crate::util::{atom_text, atom_xhtml};
use crate::util::{atom_text, atom_xhtml, attr_value, decode};

/// Represents the content of an Atom entry
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
Expand Down Expand Up @@ -173,30 +174,18 @@ impl FromXml for Content {
let mut content = Content::default();

for att in atts.with_checks(false).flatten() {
match att.key {
b"xml:base" => {
content.base = Some(
att.unescape_and_decode_value(reader)
.map_err(XmlError::new)?,
)
match decode(att.key.as_ref(), reader)? {
Cow::Borrowed("xml:base") => {
content.base = Some(attr_value(&att, reader)?.to_string());
}
b"xml:lang" => {
content.lang = Some(
att.unescape_and_decode_value(reader)
.map_err(XmlError::new)?,
)
Cow::Borrowed("xml:lang") => {
content.lang = Some(attr_value(&att, reader)?.to_string());
}
b"type" => {
content.content_type = Some(
att.unescape_and_decode_value(reader)
.map_err(XmlError::new)?,
)
Cow::Borrowed("type") => {
content.content_type = Some(attr_value(&att, reader)?.to_string());
}
b"src" => {
content.src = Some(
att.unescape_and_decode_value(reader)
.map_err(XmlError::new)?,
)
Cow::Borrowed("src") => {
content.src = Some(attr_value(&att, reader)?.to_string());
}
_ => {}
}
Expand All @@ -213,8 +202,8 @@ impl FromXml for Content {

impl ToXml for Content {
fn to_xml<W: Write>(&self, writer: &mut Writer<W>) -> Result<(), XmlError> {
let name = b"content";
let mut element = BytesStart::borrowed(name, name.len());
let name = "content";
let mut element = BytesStart::new(name);

if let Some(ref base) = self.base {
element.push_attribute(("xml:base", base.as_str()));
Expand Down Expand Up @@ -244,16 +233,16 @@ impl ToXml for Content {
writer
.write_event(Event::Text(
if self.content_type.as_deref() == Some("xhtml") {
BytesText::from_escaped(value.as_bytes())
BytesText::from_escaped(value)
} else {
BytesText::from_plain(value.as_bytes())
BytesText::new(value)
},
))
.map_err(XmlError::new)?;
}

writer
.write_event(Event::End(BytesEnd::borrowed(name)))
.write_event(Event::End(BytesEnd::new(name)))
.map_err(XmlError::new)?;

Ok(())
Expand All @@ -272,6 +261,7 @@ impl ContentBuilder {
mod test {
use super::*;
use crate::error::Error;
use crate::util::decode;

fn lines(text: &str) -> Vec<&str> {
text.lines()
Expand All @@ -293,9 +283,9 @@ mod test {

loop {
let mut buf = Vec::new();
match reader.read_event(&mut buf).map_err(XmlError::new)? {
match reader.read_event_into(&mut buf).map_err(XmlError::new)? {
Event::Start(element) => {
if element.name() == b"content" {
if decode(element.name().as_ref(), &reader)? == "content" {
let content = Content::from_xml(&mut reader, element.attributes())?;
return Ok(content);
} else {
Expand Down
69 changes: 37 additions & 32 deletions src/entry.rs
@@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::io::{BufRead, Write};

use quick_xml::events::attributes::Attributes;
Expand All @@ -16,7 +17,7 @@ use crate::person::Person;
use crate::source::Source;
use crate::text::Text;
use crate::toxml::{ToXml, WriterExt};
use crate::util::{atom_datetime, atom_text, default_fixed_datetime, FixedDateTime};
use crate::util::{atom_datetime, atom_text, decode, default_fixed_datetime, skip, FixedDateTime};

/// Represents an entry in an Atom feed
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
Expand Down Expand Up @@ -512,39 +513,45 @@ impl FromXml for Entry {
let mut buf = Vec::new();

loop {
match reader.read_event(&mut buf).map_err(XmlError::new)? {
Event::Start(element) => match element.name() {
b"id" => entry.id = atom_text(reader)?.unwrap_or_default(),
b"title" => entry.title = Text::from_xml(reader, element.attributes())?,
b"updated" => {
match reader.read_event_into(&mut buf).map_err(XmlError::new)? {
Event::Start(element) => match decode(element.name().as_ref(), reader)? {
Cow::Borrowed("id") => entry.id = atom_text(reader)?.unwrap_or_default(),
Cow::Borrowed("title") => {
entry.title = Text::from_xml(reader, element.attributes())?
}
Cow::Borrowed("updated") => {
entry.updated =
atom_datetime(reader)?.unwrap_or_else(default_fixed_datetime)
}
b"author" => entry
Cow::Borrowed("author") => entry
.authors
.push(Person::from_xml(reader, element.attributes())?),
b"category" => entry
.categories
.push(Category::from_xml(reader, element.attributes())?),
b"contributor" => entry
Cow::Borrowed("category") => {
entry.categories.push(Category::from_xml(reader, &element)?);
skip(element.name(), reader)?;
}
Cow::Borrowed("contributor") => entry
.contributors
.push(Person::from_xml(reader, element.attributes())?),
b"link" => entry
.links
.push(Link::from_xml(reader, element.attributes())?),
b"published" => entry.published = atom_datetime(reader)?,
b"rights" => entry.rights = Some(Text::from_xml(reader, element.attributes())?),
b"source" => {
Cow::Borrowed("link") => {
entry.links.push(Link::from_xml(reader, &element)?);
skip(element.name(), reader)?;
}
Cow::Borrowed("published") => entry.published = atom_datetime(reader)?,
Cow::Borrowed("rights") => {
entry.rights = Some(Text::from_xml(reader, element.attributes())?)
}
Cow::Borrowed("source") => {
entry.source = Some(Source::from_xml(reader, element.attributes())?)
}
b"summary" => {
Cow::Borrowed("summary") => {
entry.summary = Some(Text::from_xml(reader, element.attributes())?)
}
b"content" => {
Cow::Borrowed("content") => {
entry.content = Some(Content::from_xml(reader, element.attributes())?)
}
n => {
if let Some((ns, name)) = extension_name(element.name()) {
if let Some((ns, name)) = extension_name(n.as_ref()) {
parse_extension(
reader,
element.attributes(),
Expand All @@ -553,9 +560,7 @@ impl FromXml for Entry {
&mut entry.extensions,
)?;
} else {
reader
.read_to_end(n, &mut Vec::new())
.map_err(XmlError::new)?;
skip(element.name(), reader)?;
}
}
},
Expand All @@ -573,32 +578,32 @@ impl FromXml for Entry {

impl ToXml for Entry {
fn to_xml<W: Write>(&self, writer: &mut Writer<W>) -> Result<(), XmlError> {
let name = b"entry";
let name = "entry";
writer
.write_event(Event::Start(BytesStart::borrowed(name, name.len())))
.write_event(Event::Start(BytesStart::new(name)))
.map_err(XmlError::new)?;
writer.write_object_named(&self.title, b"title")?;
writer.write_text_element(b"id", &*self.id)?;
writer.write_text_element(b"updated", &*self.updated.to_rfc3339())?;
writer.write_object_named(&self.title, "title")?;
writer.write_text_element("id", &self.id)?;
writer.write_text_element("updated", &self.updated.to_rfc3339())?;
writer.write_objects_named(&self.authors, "author")?;
writer.write_objects(&self.categories)?;
writer.write_objects_named(&self.contributors, "contributor")?;
writer.write_objects(&self.links)?;

if let Some(ref published) = self.published {
writer.write_text_element(b"published", &published.to_rfc3339())?;
writer.write_text_element("published", &published.to_rfc3339())?;
}

if let Some(ref rights) = self.rights {
writer.write_object_named(rights, b"rights")?;
writer.write_object_named(rights, "rights")?;
}

if let Some(ref source) = self.source {
writer.write_object(source)?;
}

if let Some(ref summary) = self.summary {
writer.write_object_named(summary, b"summary")?;
writer.write_object_named(summary, "summary")?;
}

if let Some(ref content) = self.content {
Expand All @@ -612,7 +617,7 @@ impl ToXml for Entry {
}

writer
.write_event(Event::End(BytesEnd::borrowed(name)))
.write_event(Event::End(BytesEnd::new(name)))
.map_err(XmlError::new)?;

Ok(())
Expand Down
7 changes: 3 additions & 4 deletions src/extension/mod.rs
Expand Up @@ -182,16 +182,15 @@ impl Extension {

impl ToXml for Extension {
fn to_xml<W: Write>(&self, writer: &mut Writer<W>) -> Result<(), XmlError> {
let name = self.name.as_bytes();
let mut element = BytesStart::borrowed(name, name.len());
let mut element = BytesStart::new(&self.name);
element.extend_attributes(self.attrs.iter().map(|a| (a.0.as_bytes(), a.1.as_bytes())));
writer
.write_event(Event::Start(element))
.map_err(XmlError::new)?;

if let Some(value) = self.value.as_ref() {
writer
.write_event(Event::Text(BytesText::from_escaped(value.as_bytes())))
.write_event(Event::Text(BytesText::new(value)))
.map_err(XmlError::new)?;
}

Expand All @@ -200,7 +199,7 @@ impl ToXml for Extension {
}

writer
.write_event(Event::End(BytesEnd::borrowed(name)))
.write_event(Event::End(BytesEnd::new(&self.name)))
.map_err(XmlError::new)?;
Ok(())
}
Expand Down