mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 22:52:22 +00:00
xml: Support CDATA
This commit is contained in:
@@ -111,7 +111,8 @@ impl NamedStruct {
|
|||||||
if untagged_field_branches.len() > 1 {
|
if untagged_field_branches.len() > 1 {
|
||||||
panic!("Currently only one untagged field supported!");
|
panic!("Currently only one untagged field supported!");
|
||||||
}
|
}
|
||||||
let text_field_branches = self.fields.iter().filter_map(Field::text_branch);
|
let text_field_branches: Vec<_> =
|
||||||
|
self.fields.iter().filter_map(Field::text_branch).collect();
|
||||||
let attr_field_branches = self.fields.iter().filter_map(Field::attr_branch);
|
let attr_field_branches = self.fields.iter().filter_map(Field::attr_branch);
|
||||||
let tagname_field_branches = self.fields.iter().filter_map(Field::tagname_branch);
|
let tagname_field_branches = self.fields.iter().filter_map(Field::tagname_branch);
|
||||||
|
|
||||||
@@ -175,7 +176,8 @@ impl NamedStruct {
|
|||||||
#(#text_field_branches)*
|
#(#text_field_branches)*
|
||||||
}
|
}
|
||||||
Event::CData(cdata) => {
|
Event::CData(cdata) => {
|
||||||
return Err(XmlError::UnsupportedEvent("CDATA"));
|
let text = String::from_utf8(cdata.to_vec())?;
|
||||||
|
#(#text_field_branches)*
|
||||||
}
|
}
|
||||||
Event::Comment(_) => { /* ignore */ }
|
Event::Comment(_) => { /* ignore */ }
|
||||||
Event::Decl(_) => {
|
Event::Decl(_) => {
|
||||||
@@ -191,7 +193,7 @@ impl NamedStruct {
|
|||||||
return Err(XmlError::UnsupportedEvent("Doctype in the middle of the document"));
|
return Err(XmlError::UnsupportedEvent("Doctype in the middle of the document"));
|
||||||
}
|
}
|
||||||
Event::End(end) => {
|
Event::End(end) => {
|
||||||
// Error: premature end
|
// This should actually be unreachable
|
||||||
return Err(XmlError::Other("Unexpected closing tag for wrong element".to_owned()));
|
return Err(XmlError::Other("Unexpected closing tag for wrong element".to_owned()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::string::FromUtf8Error;
|
||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
@@ -6,6 +8,8 @@ pub enum XmlError {
|
|||||||
QuickXmlError(#[from] quick_xml::Error),
|
QuickXmlError(#[from] quick_xml::Error),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
QuickXmlAttrError(#[from] quick_xml::events::attributes::AttrError),
|
QuickXmlAttrError(#[from] quick_xml::events::attributes::AttrError),
|
||||||
|
#[error(transparent)]
|
||||||
|
FromUtf8Error(#[from] FromUtf8Error),
|
||||||
#[error("Invalid tag [{0}]{1}. Expected [{2}]{3}")]
|
#[error("Invalid tag [{0}]{1}. Expected [{2}]{3}")]
|
||||||
InvalidTag(String, String, String, String),
|
InvalidTag(String, String, String, String),
|
||||||
#[error("Missing field {0}")]
|
#[error("Missing field {0}")]
|
||||||
|
|||||||
@@ -81,6 +81,14 @@ impl<T: ValueDeserialize> XmlDeserialize for T {
|
|||||||
}
|
}
|
||||||
string = String::from_utf8_lossy(text.as_ref()).to_string();
|
string = String::from_utf8_lossy(text.as_ref()).to_string();
|
||||||
}
|
}
|
||||||
|
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 = text;
|
||||||
|
}
|
||||||
Event::End(_) => break,
|
Event::End(_) => break,
|
||||||
Event::Eof => return Err(XmlError::Eof),
|
Event::Eof => return Err(XmlError::Eof),
|
||||||
_ => return Err(XmlError::UnsupportedEvent("todo")),
|
_ => return Err(XmlError::UnsupportedEvent("todo")),
|
||||||
|
|||||||
@@ -257,6 +257,34 @@ fn test_xml_values() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_xml_cdata() {
|
||||||
|
#[derive(XmlDeserialize, XmlRootTag, PartialEq, Debug)]
|
||||||
|
#[xml(root = b"document")]
|
||||||
|
struct Document {
|
||||||
|
#[xml(ty = "text")]
|
||||||
|
hello: String,
|
||||||
|
href: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
let doc = Document::parse_str(
|
||||||
|
r#"
|
||||||
|
<document>
|
||||||
|
<![CDATA[some text]]>
|
||||||
|
<href><![CDATA[some stuff]]></href>
|
||||||
|
</document>
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
doc,
|
||||||
|
Document {
|
||||||
|
hello: "some text".to_owned(),
|
||||||
|
href: "some stuff".to_owned()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_struct_xml_decl() {
|
fn test_struct_xml_decl() {
|
||||||
#[derive(Debug, XmlDeserialize, XmlRootTag, PartialEq)]
|
#[derive(Debug, XmlDeserialize, XmlRootTag, PartialEq)]
|
||||||
|
|||||||
Reference in New Issue
Block a user