xml: Implement proper NamespaceOwned type

This commit is contained in:
Lennart
2025-05-14 20:18:45 +02:00
parent 1436af1f9c
commit 212274fce9
8 changed files with 53 additions and 15 deletions

View File

@@ -165,8 +165,8 @@ mod tests {
report_request, report_request,
ReportRequest::CalendarMultiget(CalendarMultigetRequest { ReportRequest::CalendarMultiget(CalendarMultigetRequest {
prop: rustical_dav::xml::PropfindType::Prop(PropElement(vec![ prop: rustical_dav::xml::PropfindType::Prop(PropElement(vec![
ReportPropName::Propname(Propname{name: "getetag".to_owned(), ns: Some("DAV:".to_owned())}), ReportPropName::Propname(Propname{name: "getetag".to_owned(), ns: Some("DAV:".into())}),
ReportPropName::Propname(Propname{name: "displayname".to_owned(), ns: Some("DAV:".to_owned())}), ReportPropName::Propname(Propname{name: "displayname".to_owned(), ns: Some("DAV:".into())}),
ReportPropName::CalendarData(CalendarData { comp: None, expand: Some(ExpandElement { start: "20250426T220000Z".to_owned(), end: "20250503T220000Z".to_owned() }), limit_recurrence_set: None, limit_freebusy_set: None }) ReportPropName::CalendarData(CalendarData { comp: None, expand: Some(ExpandElement { start: "20250426T220000Z".to_owned(), end: "20250503T220000Z".to_owned() }), limit_recurrence_set: None, limit_freebusy_set: None })
])), ])),
href: vec![ href: vec![
@@ -200,7 +200,7 @@ mod tests {
ReportRequest::CalendarQuery(CalendarQueryRequest { ReportRequest::CalendarQuery(CalendarQueryRequest {
prop: PropfindType::Prop(PropElement(vec![ReportPropName::Propname(Propname { prop: PropfindType::Prop(PropElement(vec![ReportPropName::Propname(Propname {
name: "getetag".to_owned(), name: "getetag".to_owned(),
ns: Some("DAV:".to_owned()) ns: Some("DAV:".into())
})])), })])),
filter: Some(FilterElement { filter: Some(FilterElement {
comp_filter: CompFilterElement { comp_filter: CompFilterElement {
@@ -248,8 +248,8 @@ mod tests {
report_request, report_request,
ReportRequest::CalendarMultiget(CalendarMultigetRequest { ReportRequest::CalendarMultiget(CalendarMultigetRequest {
prop: rustical_dav::xml::PropfindType::Prop(PropElement(vec![ prop: rustical_dav::xml::PropfindType::Prop(PropElement(vec![
ReportPropName::Propname(Propname{name: "getetag".to_owned(), ns: Some("DAV:".to_owned())}), ReportPropName::Propname(Propname{name: "getetag".to_owned(), ns: Some("DAV:".into())}),
ReportPropName::Propname(Propname{name: "displayname".to_owned(), ns: Some("DAV:".to_owned())}) ReportPropName::Propname(Propname{name: "displayname".to_owned(), ns: Some("DAV:".into())})
])), ])),
href: vec![ href: vec![
"/caldav/user/user/6f787542-5256-401a-8db97003260da/ae7a998fdfd1d84a20391168962c62b".to_owned() "/caldav/user/user/6f787542-5256-401a-8db97003260da/ae7a998fdfd1d84a20391168962c62b".to_owned()

View File

@@ -114,7 +114,7 @@ mod tests {
sync_level: SyncLevel::One, sync_level: SyncLevel::One,
prop: rustical_dav::xml::PropfindType::Prop(PropElement(vec![Propname { prop: rustical_dav::xml::PropfindType::Prop(PropElement(vec![Propname {
name: "getetag".to_owned(), name: "getetag".to_owned(),
ns: Some("DAV:".to_owned()) ns: Some("DAV:".into())
}])), }])),
limit: None limit: None
}) })
@@ -138,8 +138,8 @@ mod tests {
report_request, report_request,
ReportRequest::AddressbookMultiget(AddressbookMultigetRequest { ReportRequest::AddressbookMultiget(AddressbookMultigetRequest {
prop: rustical_dav::xml::PropfindType::Prop(PropElement(vec![ prop: rustical_dav::xml::PropfindType::Prop(PropElement(vec![
Propname{name: "getetag".to_owned(), ns: Some("DAV:".to_owned())}, Propname{name: "getetag".to_owned(), ns: Some("DAV:".into())},
Propname{name: "address-data".to_owned(), ns: Some("urn:ietf:params:xml:ns:carddav".to_owned())} Propname{name: "address-data".to_owned(), ns: Some("urn:ietf:params:xml:ns:carddav".into())}
])), ])),
href: vec![ href: vec![
"/carddav/user/user/6f787542-5256-401a-8db97003260da/ae7a998fdfd1d84a20391168962c62b".to_owned() "/carddav/user/user/6f787542-5256-401a-8db97003260da/ae7a998fdfd1d84a20391168962c62b".to_owned()

View File

@@ -1,3 +1,4 @@
use rustical_xml::NamespaceOwned;
use rustical_xml::XmlDeserialize; use rustical_xml::XmlDeserialize;
use rustical_xml::XmlRootTag; use rustical_xml::XmlRootTag;
@@ -14,7 +15,7 @@ pub struct PropElement<PN: XmlDeserialize = Propname>(#[xml(ty = "untagged", fla
#[derive(Debug, Clone, XmlDeserialize, PartialEq)] #[derive(Debug, Clone, XmlDeserialize, PartialEq)]
pub struct Propname { pub struct Propname {
#[xml(ty = "namespace")] #[xml(ty = "namespace")]
pub ns: Option<String>, pub ns: Option<NamespaceOwned>,
#[xml(ty = "tag_name")] #[xml(ty = "tag_name")]
pub name: String, pub name: String,
} }

View File

@@ -56,11 +56,11 @@ fn propfind_prop() {
prop: PropfindType::Prop(PropElement(vec![ prop: PropfindType::Prop(PropElement(vec![
Propname { Propname {
name: "displayname".to_owned(), name: "displayname".to_owned(),
ns: Some("DAV:".to_owned()) ns: Some("DAV:".to_owned().into())
}, },
Propname { Propname {
name: "color".to_owned(), name: "color".to_owned(),
ns: Some("DAV:".to_owned()) ns: Some("DAV:".to_owned().into())
}, },
])) ]))
} }

View File

@@ -254,7 +254,8 @@ impl Field {
let value = quote! { let value = quote! {
if let ::quick_xml::name::ResolveResult::Bound(ns) = &ns { if let ::quick_xml::name::ResolveResult::Bound(ns) = &ns {
Some(rustical_xml::ValueDeserialize::deserialize(&String::from_utf8_lossy(ns.0.as_ref()))?) Some(ns.into())
// Some(rustical_xml::ValueDeserialize::deserialize(&String::from_utf8_lossy(ns.0.as_ref()))?)
} else { } else {
None None
} }

View File

@@ -4,6 +4,7 @@ use std::str::FromStr;
pub mod de; pub mod de;
mod error; mod error;
mod namespace;
pub mod se; pub mod se;
mod unparsed; mod unparsed;
mod value; mod value;
@@ -11,6 +12,7 @@ mod value;
pub use de::XmlDeserialize; pub use de::XmlDeserialize;
pub use de::XmlDocument; pub use de::XmlDocument;
pub use error::XmlError; pub use error::XmlError;
pub use namespace::NamespaceOwned;
pub use se::XmlSerialize; pub use se::XmlSerialize;
pub use se::XmlSerializeRoot; pub use se::XmlSerializeRoot;
pub use unparsed::Unparsed; pub use unparsed::Unparsed;

View File

@@ -0,0 +1,34 @@
use quick_xml::name::Namespace;
#[derive(Debug, Clone, Default, PartialEq)]
pub struct NamespaceOwned(pub Vec<u8>);
impl<'a> From<Namespace<'a>> for NamespaceOwned {
fn from(value: Namespace<'a>) -> Self {
Self(value.0.to_vec())
}
}
impl From<String> for NamespaceOwned {
fn from(value: String) -> Self {
Self(value.into_bytes())
}
}
impl From<&str> for NamespaceOwned {
fn from(value: &str) -> Self {
Self(value.as_bytes().to_vec())
}
}
impl<'a> From<&'a Namespace<'a>> for NamespaceOwned {
fn from(value: &'a Namespace<'a>) -> Self {
Self(value.0.to_vec())
}
}
impl NamespaceOwned {
pub fn as_ref(&self) -> Namespace {
Namespace(&self.0)
}
}

View File

@@ -1,6 +1,6 @@
use quick_xml::name::Namespace; use quick_xml::name::Namespace;
use rustical_xml::de::XmlDocument; use rustical_xml::de::XmlDocument;
use rustical_xml::{Unparsed, XmlDeserialize, XmlRootTag}; use rustical_xml::{NamespaceOwned, Unparsed, XmlDeserialize, XmlRootTag};
use std::collections::HashSet; use std::collections::HashSet;
#[test] #[test]
@@ -355,7 +355,7 @@ fn test_struct_untagged_ns() {
#[derive(Debug, XmlDeserialize, PartialEq, Default)] #[derive(Debug, XmlDeserialize, PartialEq, Default)]
struct Child( struct Child(
#[xml(ty = "tag_name")] String, #[xml(ty = "tag_name")] String,
#[xml(ty = "namespace")] Option<String>, #[xml(ty = "namespace")] Option<NamespaceOwned>,
); );
let doc = Document::parse_str( let doc = Document::parse_str(
@@ -367,7 +367,7 @@ fn test_struct_untagged_ns() {
assert_eq!( assert_eq!(
doc, doc,
Document { Document {
child: Child("test".to_owned(), Some("hello".to_string())) child: Child("test".to_owned(), Some("hello".to_string().into()))
} }
); );
} }