mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-14 11:42:25 +00:00
xml: namespace serialization
This commit is contained in:
@@ -1,47 +1,9 @@
|
||||
use quick_xml::events::attributes::Attribute;
|
||||
use quick_xml::name::Namespace;
|
||||
|
||||
// An enum keeping track of the XML namespaces used for WebDAV and its extensions
|
||||
//
|
||||
// Can also generate appropriate attributes for quick_xml
|
||||
pub enum Namespace {
|
||||
Dav,
|
||||
DavPush,
|
||||
CalDAV,
|
||||
CardDAV,
|
||||
ICal,
|
||||
CServer,
|
||||
Nextcloud,
|
||||
}
|
||||
|
||||
impl Namespace {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Dav => "DAV:",
|
||||
Self::DavPush => "DAV:Push",
|
||||
Self::CalDAV => "urn:ietf:params:xml:ns:caldav",
|
||||
Self::CardDAV => "urn:ietf:params:xml:ns:carddav",
|
||||
Self::ICal => "http://apple.com/ns/ical/",
|
||||
Self::CServer => "http://calendarserver.org/ns/",
|
||||
Self::Nextcloud => "http://nextcloud.com/ns",
|
||||
}
|
||||
}
|
||||
|
||||
// Returns an opinionated namespace attribute name
|
||||
pub fn xml_attr(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Dav => "xmlns",
|
||||
Self::DavPush => "xmlns:P",
|
||||
Self::CalDAV => "xmlns:C",
|
||||
Self::CardDAV => "xmlns:CARD",
|
||||
Self::ICal => "xmlns:IC",
|
||||
Self::CServer => "xmlns:CS",
|
||||
Self::Nextcloud => "xmlns:NEXTC",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Namespace> for Attribute<'static> {
|
||||
fn from(value: Namespace) -> Self {
|
||||
(value.xml_attr(), value.as_str()).into()
|
||||
}
|
||||
}
|
||||
pub const NS_DAV: Namespace = Namespace(b"DAV:");
|
||||
pub const NS_DAVPUSH: Namespace = Namespace(b"DAV:Push");
|
||||
pub const NS_CALDAV: Namespace = Namespace(b"urn:ietf:params:xml:ns:caldav");
|
||||
pub const NS_CARDDAV: Namespace = Namespace(b"urn:ietf:params:xml:ns:carddav");
|
||||
pub const NS_ICAL: Namespace = Namespace(b"http://apple.com/ns/ical/");
|
||||
pub const NS_CALENDARSERVER: Namespace = Namespace(b"http://calendarserver.org/ns/");
|
||||
pub const NS_NEXTCLOUD: Namespace = Namespace(b"http://nextcloud.com/ns");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use quick_xml::name::Namespace;
|
||||
use rustical_xml::{XmlDeserialize, XmlSerialize};
|
||||
use std::collections::HashSet;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
#[derive(Debug, Clone, XmlSerialize, XmlDeserialize, Eq, Hash, PartialEq)]
|
||||
pub enum UserPrivilege {
|
||||
@@ -16,8 +17,9 @@ pub enum UserPrivilege {
|
||||
impl XmlSerialize for UserPrivilegeSet {
|
||||
fn serialize<W: std::io::Write>(
|
||||
&self,
|
||||
ns: Option<&[u8]>,
|
||||
ns: Option<Namespace>,
|
||||
tag: Option<&[u8]>,
|
||||
namespaces: &HashMap<Namespace, &[u8]>,
|
||||
writer: &mut quick_xml::Writer<W>,
|
||||
) -> std::io::Result<()> {
|
||||
#[derive(XmlSerialize)]
|
||||
@@ -29,7 +31,7 @@ impl XmlSerialize for UserPrivilegeSet {
|
||||
FakeUserPrivilegeSet {
|
||||
privileges: self.privileges.iter().cloned().collect(),
|
||||
}
|
||||
.serialize(ns, tag, writer)
|
||||
.serialize(ns, tag, namespaces, writer)
|
||||
}
|
||||
|
||||
#[allow(refining_impl_trait)]
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
use crate::{namespace::Namespace, xml::TagList};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::xml::TagList;
|
||||
use actix_web::{
|
||||
body::BoxBody,
|
||||
http::{header::ContentType, StatusCode},
|
||||
HttpRequest, HttpResponse, Responder, ResponseError,
|
||||
};
|
||||
use quick_xml::name::Namespace;
|
||||
use rustical_xml::{XmlRootTag, XmlSerialize, XmlSerializeRoot};
|
||||
|
||||
// Intermediate struct because of a serde limitation, see following article:
|
||||
@@ -25,11 +28,12 @@ pub struct PropstatElement<PropType: XmlSerialize> {
|
||||
|
||||
fn xml_serialize_status<W: ::std::io::Write>(
|
||||
status: &StatusCode,
|
||||
ns: Option<&[u8]>,
|
||||
ns: Option<Namespace>,
|
||||
tag: Option<&[u8]>,
|
||||
namespaces: &HashMap<Namespace, &[u8]>,
|
||||
writer: &mut quick_xml::Writer<W>,
|
||||
) -> std::io::Result<()> {
|
||||
XmlSerialize::serialize(&format!("HTTP/1.1 {}", status), ns, tag, writer)
|
||||
XmlSerialize::serialize(&format!("HTTP/1.1 {}", status), ns, tag, namespaces, writer)
|
||||
}
|
||||
|
||||
#[derive(XmlSerialize)]
|
||||
@@ -53,14 +57,16 @@ pub struct ResponseElement<PropstatType: XmlSerialize> {
|
||||
|
||||
fn xml_serialize_optional_status<W: ::std::io::Write>(
|
||||
val: &Option<StatusCode>,
|
||||
ns: Option<&[u8]>,
|
||||
ns: Option<Namespace>,
|
||||
tag: Option<&[u8]>,
|
||||
namespaces: &HashMap<Namespace, &[u8]>,
|
||||
writer: &mut quick_xml::Writer<W>,
|
||||
) -> std::io::Result<()> {
|
||||
XmlSerialize::serialize(
|
||||
&val.map(|status| format!("HTTP/1.1 {}", status)),
|
||||
ns,
|
||||
tag,
|
||||
namespaces,
|
||||
writer,
|
||||
)
|
||||
}
|
||||
@@ -86,12 +92,12 @@ pub struct MultistatusElement<PropType: XmlSerialize, MemberPropType: XmlSeriali
|
||||
#[xml(rename = b"response", flatten)]
|
||||
pub member_responses: Vec<ResponseElement<MemberPropType>>,
|
||||
// TODO: napespaces
|
||||
pub ns_dav: &'static str,
|
||||
pub ns_davpush: &'static str,
|
||||
pub ns_caldav: &'static str,
|
||||
pub ns_ical: &'static str,
|
||||
pub ns_calendarserver: &'static str,
|
||||
pub ns_carddav: &'static str,
|
||||
// pub ns_dav: &'static str,
|
||||
// pub ns_davpush: &'static str,
|
||||
// pub ns_caldav: &'static str,
|
||||
// pub ns_ical: &'static str,
|
||||
// pub ns_calendarserver: &'static str,
|
||||
// pub ns_carddav: &'static str,
|
||||
pub sync_token: Option<String>,
|
||||
}
|
||||
|
||||
@@ -100,12 +106,12 @@ impl<T1: XmlSerialize, T2: XmlSerialize> Default for MultistatusElement<T1, T2>
|
||||
Self {
|
||||
responses: vec![],
|
||||
member_responses: vec![],
|
||||
ns_dav: Namespace::Dav.as_str(),
|
||||
ns_davpush: Namespace::DavPush.as_str(),
|
||||
ns_caldav: Namespace::CalDAV.as_str(),
|
||||
ns_ical: Namespace::ICal.as_str(),
|
||||
ns_calendarserver: Namespace::CServer.as_str(),
|
||||
ns_carddav: Namespace::CardDAV.as_str(),
|
||||
// ns_dav: Namespace::Dav.as_str(),
|
||||
// ns_davpush: Namespace::DavPush.as_str(),
|
||||
// ns_caldav: Namespace::CalDAV.as_str(),
|
||||
// ns_ical: Namespace::ICal.as_str(),
|
||||
// ns_calendarserver: Namespace::CServer.as_str(),
|
||||
// ns_carddav: Namespace::CardDAV.as_str(),
|
||||
sync_token: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use rustical_xml::XmlDeserialize;
|
||||
use rustical_xml::XmlRootTag;
|
||||
|
||||
#[derive(Debug, Clone, XmlDeserialize, XmlRootTag, PartialEq)]
|
||||
#[xml(root = b"propfind", ns = b"DAV:")]
|
||||
#[xml(root = b"propfind", ns = "crate::namespace::NS_DAV")]
|
||||
pub struct PropfindElement {
|
||||
#[xml(ty = "untagged")]
|
||||
pub prop: PropfindType,
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use quick_xml::events::attributes::Attribute;
|
||||
use quick_xml::events::{BytesEnd, BytesStart, Event};
|
||||
use quick_xml::name::Namespace;
|
||||
use rustical_xml::XmlSerialize;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
@@ -8,8 +11,9 @@ pub struct Resourcetype(pub &'static [&'static str]);
|
||||
impl XmlSerialize for Resourcetype {
|
||||
fn serialize<W: std::io::Write>(
|
||||
&self,
|
||||
ns: Option<&[u8]>,
|
||||
ns: Option<Namespace>,
|
||||
tag: Option<&[u8]>,
|
||||
namespaces: &HashMap<Namespace, &[u8]>,
|
||||
writer: &mut quick_xml::Writer<W>,
|
||||
) -> std::io::Result<()> {
|
||||
let tag_str = tag.map(String::from_utf8_lossy);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use derive_more::derive::From;
|
||||
use quick_xml::name::Namespace;
|
||||
use rustical_xml::XmlSerialize;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, From)]
|
||||
pub struct TagList(Vec<String>);
|
||||
@@ -7,8 +9,9 @@ pub struct TagList(Vec<String>);
|
||||
impl XmlSerialize for TagList {
|
||||
fn serialize<W: std::io::Write>(
|
||||
&self,
|
||||
ns: Option<&[u8]>,
|
||||
ns: Option<Namespace>,
|
||||
tag: Option<&[u8]>,
|
||||
namespaces: &HashMap<Namespace, &[u8]>,
|
||||
writer: &mut quick_xml::Writer<W>,
|
||||
) -> std::io::Result<()> {
|
||||
#[derive(Debug, XmlSerialize, PartialEq)]
|
||||
@@ -25,7 +28,7 @@ impl XmlSerialize for TagList {
|
||||
Inner {
|
||||
tags: self.0.iter().map(|t| Tag { name: t.to_owned() }).collect(),
|
||||
}
|
||||
.serialize(ns, tag, writer)
|
||||
.serialize(ns, tag, namespaces, writer)
|
||||
}
|
||||
|
||||
#[allow(refining_impl_trait)]
|
||||
|
||||
Reference in New Issue
Block a user