migrate quick-xml to 0.38

fixes #120
This commit is contained in:
Lennart
2025-09-05 15:24:34 +02:00
parent 87adf94947
commit 91586ee797
12 changed files with 81 additions and 47 deletions

View File

@@ -66,6 +66,9 @@ impl<PN: XmlDeserialize> XmlDeserialize for PropElement<PN> {
Event::Text(_) | Event::CData(_) => {
return Err(XmlError::UnsupportedEvent("Not expecting text here"));
}
Event::GeneralRef(_) => {
return Err(::rustical_xml::XmlError::UnsupportedEvent("GeneralRef"));
}
Event::Decl(_) | Event::Comment(_) | Event::DocType(_) | Event::PI(_) => { /* ignore */
}
Event::End(_end) => {

View File

@@ -29,12 +29,9 @@ impl XmlSerialize for TagList {
});
let has_prefix = prefix.is_some();
let tagname = tag.map(|tag| [&prefix.unwrap_or_default(), tag].concat());
let qname = tagname
.as_ref()
.map(|tagname| ::quick_xml::name::QName(tagname.as_bytes()));
if let Some(qname) = &qname {
let mut bytes_start = BytesStart::from(qname.to_owned());
if let Some(tagname) = tagname.as_ref() {
let mut bytes_start = BytesStart::new(tagname);
if !has_prefix && let Some(ns) = &ns {
bytes_start.push_attribute((b"xmlns".as_ref(), ns.as_ref()));
}
@@ -49,8 +46,8 @@ impl XmlSerialize for TagList {
el.write_empty()?;
}
if let Some(qname) = &qname {
writer.write_event(Event::End(BytesEnd::from(qname.to_owned())))?;
if let Some(tagname) = tagname.as_ref() {
writer.write_event(Event::End(BytesEnd::new(tagname)))?;
}
Ok(())
}

View File

@@ -34,12 +34,11 @@ impl Enum {
});
let has_prefix = prefix.is_some();
let tagname = tag.map(|tag| [&prefix.unwrap_or_default(), tag].concat());
let qname = tagname.as_ref().map(|tagname| ::quick_xml::name::QName(tagname.as_bytes()));
const enum_untagged: bool = #enum_untagged;
if let Some(qname) = &qname {
let mut bytes_start = BytesStart::from(qname.to_owned());
if let Some(tagname) = tagname.as_ref() {
let mut bytes_start = BytesStart::new(tagname);
if !has_prefix {
if let Some(ns) = &ns {
bytes_start.push_attribute((b"xmlns".as_ref(), ns.as_ref()));
@@ -50,8 +49,8 @@ impl Enum {
#(#variant_serializers);*
if let Some(qname) = &qname {
writer.write_event(Event::End(BytesEnd::from(qname.to_owned())))?;
if let Some(tagname) = tagname.as_ref() {
writer.write_event(Event::End(BytesEnd::new(tagname)))?;
}
Ok(())
}

View File

@@ -66,6 +66,9 @@ impl Enum {
Event::CData(cdata) => {
return Err(::rustical_xml::XmlError::UnsupportedEvent("CDATA"));
}
Event::GeneralRef(_) => {
return Err(::rustical_xml::XmlError::UnsupportedEvent("GeneralRef"));
}
Event::Decl(_) => { /* <?xml ... ?> ignore this */ }
Event::Comment(_) => { /* ignore */ }
Event::DocType(_) => { /* ignore */ }

View File

@@ -111,10 +111,9 @@ impl NamedStruct {
});
let has_prefix = prefix.is_some();
let tagname = tag.map(|tag| [&prefix.unwrap_or_default(), tag].concat());
let qname = tagname.as_ref().map(|tagname| ::quick_xml::name::QName(tagname.as_bytes()));
if let Some(qname) = &qname {
let mut bytes_start = BytesStart::from(qname.to_owned());
if let Some(tagname) = tagname.as_ref() {
let mut bytes_start = BytesStart::new(tagname);
if !has_prefix {
if let Some(ns) = &ns {
bytes_start.push_attribute((b"xmlns".as_ref(), ns.as_ref()));
@@ -133,8 +132,8 @@ impl NamedStruct {
}
if !#is_empty {
#(#tag_writers);*
if let Some(qname) = &qname {
writer.write_event(Event::End(BytesEnd::from(qname.to_owned())))?;
if let Some(tagname) = tagname.as_ref() {
writer.write_event(Event::End(BytesEnd::new(tagname)))?;
}
}
Ok(())

View File

@@ -148,6 +148,8 @@ impl NamedStruct {
}
}
let mut string = String::new();
if !empty {
loop {
let event = reader.read_event_into(&mut buf)?;
@@ -167,12 +169,23 @@ impl NamedStruct {
}
}
Event::Text(bytes_text) => {
let text = bytes_text.unescape()?;
#(#text_field_branches)*
let text = bytes_text.decode()?;
string.push_str(&text);
}
Event::CData(cdata) => {
let text = String::from_utf8(cdata.to_vec())?;
#(#text_field_branches)*
string.push_str(&text);
}
Event::GeneralRef(gref) => {
if let Some(char) = gref.resolve_char_ref()? {
string.push(char);
} else if let Some(text) =
quick_xml::escape::resolve_xml_entity(&gref.xml_content()?)
{
string.push_str(text);
} else {
return Err(XmlError::UnsupportedEvent("invalid XML ref"));
}
}
Event::Decl(_) => { /* <?xml ... ?> ignore this */ }
Event::Comment(_) => { /* ignore */ }
@@ -185,6 +198,9 @@ impl NamedStruct {
}
}
let text = string;
#(#text_field_branches)*
Ok(Self {
#(#builder_field_builds),*
})

View File

@@ -8,6 +8,8 @@ pub enum XmlError {
#[error(transparent)]
QuickXmlError(#[from] quick_xml::Error),
#[error(transparent)]
QuickXmlEncodingError(#[from] quick_xml::encoding::EncodingError),
#[error(transparent)]
QuickXmlAttrError(#[from] quick_xml::events::attributes::AttrError),
#[error(transparent)]
FromUtf8Error(#[from] FromUtf8Error),

View File

@@ -1,7 +1,7 @@
use crate::XmlRootTag;
use quick_xml::{
events::{BytesStart, Event, attributes::Attribute},
name::{Namespace, QName},
name::Namespace,
};
use std::collections::HashMap;
pub use xml_derive::XmlSerialize;
@@ -76,9 +76,8 @@ impl XmlSerialize for () {
});
let has_prefix = prefix.is_some();
let tagname = tag.map(|tag| [&prefix.unwrap_or_default(), tag].concat());
let qname = tagname.as_ref().map(|tagname| QName(tagname.as_bytes()));
if let Some(qname) = &qname {
let mut bytes_start = BytesStart::from(qname.to_owned());
if let Some(tagname) = tagname.as_ref() {
let mut bytes_start = BytesStart::new(tagname);
if !has_prefix && let Some(ns) = &ns {
bytes_start.push_attribute((b"xmlns".as_ref(), ns.as_ref()));
}

View File

@@ -1,6 +1,6 @@
use crate::{XmlDeserialize, XmlError, XmlSerialize};
use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event};
use quick_xml::name::{Namespace, QName};
use quick_xml::name::Namespace;
use std::collections::HashMap;
use std::num::{ParseFloatError, ParseIntError};
use std::{convert::Infallible, io::BufRead};
@@ -77,20 +77,23 @@ impl<T: ValueDeserialize> XmlDeserialize for T {
loop {
match reader.read_event_into(&mut buf)? {
Event::Text(bytes_text) => {
let text = bytes_text.unescape()?;
if !string.is_empty() {
// Content already written
return Err(XmlError::UnsupportedEvent("content already written"));
}
string = text.to_string();
let text = bytes_text.decode()?;
string.push_str(&text);
}
Event::CData(cdata) => {
let text = String::from_utf8(cdata.to_vec())?;
if !string.is_empty() {
// Content already written
return Err(XmlError::UnsupportedEvent("content already written"));
string.push_str(&text);
}
Event::GeneralRef(gref) => {
if let Some(char) = gref.resolve_char_ref()? {
string.push(char);
} else if let Some(text) =
quick_xml::escape::resolve_xml_entity(&gref.xml_content()?)
{
string.push_str(text);
} else {
return Err(XmlError::UnsupportedEvent("invalid XML ref"));
}
string = text;
}
Event::End(_) => break,
Event::Eof => return Err(XmlError::Eof),
@@ -123,17 +126,16 @@ impl<T: ValueSerialize> XmlSerialize for T {
});
let has_prefix = prefix.is_some();
let tagname = tag.map(|tag| [&prefix.unwrap_or_default(), tag].concat());
let qname = tagname.as_ref().map(|tagname| QName(tagname.as_bytes()));
if let Some(qname) = &qname {
let mut bytes_start = BytesStart::from(qname.to_owned());
if let Some(tagname) = tagname.as_ref() {
let mut bytes_start = BytesStart::new(tagname);
if !has_prefix && let Some(ns) = &ns {
bytes_start.push_attribute((b"xmlns".as_ref(), ns.as_ref()));
}
writer.write_event(Event::Start(bytes_start))?;
}
writer.write_event(Event::Text(BytesText::new(&self.serialize())))?;
if let Some(qname) = &qname {
writer.write_event(Event::End(BytesEnd::from(qname.to_owned())))?;
if let Some(tagname) = tagname {
writer.write_event(Event::End(BytesEnd::new(tagname)))?;
}
Ok(())
}

View File

@@ -275,7 +275,7 @@ fn test_xml_cdata() {
<document>
<![CDATA[some text]]>
<href><![CDATA[some stuff]]></href>
<okay>&gt;</okay>
<okay>nice&gt;text</okay>
</document>
"#,
)
@@ -285,11 +285,25 @@ fn test_xml_cdata() {
Document {
hello: "some text".to_owned(),
href: "some stuff".to_owned(),
okay: ">".to_owned()
okay: "nice>text".to_owned()
}
);
}
#[test]
fn test_quickxml_bytesref() {
let gt = quick_xml::events::BytesRef::new("gt");
assert!(!gt.is_char_ref());
let result = if !gt.is_char_ref() {
quick_xml::escape::resolve_xml_entity(&gt.xml_content().unwrap())
.unwrap()
.to_string()
} else {
gt.xml_content().unwrap().to_string()
};
assert_eq!(result, ">");
}
#[test]
fn test_struct_xml_decl() {
#[derive(Debug, XmlDeserialize, XmlRootTag, PartialEq)]
@@ -307,14 +321,14 @@ fn test_struct_xml_decl() {
let doc = Document::parse_str(
r#"
<?xml version="1.0" encoding="utf-8"?>
<document><child>Hello!</child></document>"#,
<document><child>Hello!&amp;</child></document>"#,
)
.unwrap();
assert_eq!(
doc,
Document {
child: Child {
text: "Hello!".to_owned()
text: "Hello!&".to_owned()
}
}
);