mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 22:52:22 +00:00
@@ -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) => {
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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 */ }
|
||||
|
||||
@@ -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(())
|
||||
|
||||
@@ -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),*
|
||||
})
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ fn test_xml_cdata() {
|
||||
<document>
|
||||
<![CDATA[some text]]>
|
||||
<href><![CDATA[some stuff]]></href>
|
||||
<okay>></okay>
|
||||
<okay>nice>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(>.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!&</child></document>"#,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
doc,
|
||||
Document {
|
||||
child: Child {
|
||||
text: "Hello!".to_owned()
|
||||
text: "Hello!&".to_owned()
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user