WIP encoder

This commit is contained in:
Quentin 2024-02-29 23:02:02 +01:00
parent fadadffc92
commit 33a02ff695
Signed by: quentin
GPG key ID: E9602264D639FF68
4 changed files with 101 additions and 84 deletions

View file

@ -8,28 +8,6 @@ use quick_xml::writer::{ElementWriter, Writer};
use quick_xml::name::PrefixDeclaration; use quick_xml::name::PrefixDeclaration;
use tokio::io::AsyncWrite; use tokio::io::AsyncWrite;
/*pub trait CalWriter<E: Extension>: DavWriter<E> {
fn create_cal_element(&mut self, name: &str) -> ElementWriter<impl AsyncWrite + Unpin>;
}
impl<'a, W: AsyncWrite+Unpin> DavWriter<CalExtension> for Writer<'a, W, CalExtension> {
fn create_dav_element(&mut self, name: &str) -> ElementWriter<impl AsyncWrite + Unpin> {
self.create_ns_element(name, Namespace::Dav)
}
fn child(w: &'a mut QWriter<W>) -> impl DavWriter<CalExtension> {
Self::child(w)
}
async fn error(&mut self, err: &Violation) -> Result<(), QError> {
err.write(self).await
}
}
impl<'a, W: AsyncWrite+Unpin> CalWriter<CalExtension> for Writer<'a, W, CalExtension> {
fn create_cal_element(&mut self, name: &str) -> ElementWriter<impl AsyncWrite + Unpin> {
self.create_ns_element(name, Namespace::CalDav)
}
}*/
pub struct CalCtx { pub struct CalCtx {
root: bool root: bool
} }

View file

@ -1,25 +1,11 @@
use super::types::*; use super::types::*;
pub enum Namespace {
Dav,
CalDav,
}
pub struct CalExtension {} pub struct CalExtension {}
impl Extension for CalExtension { impl Extension for CalExtension {
type Error = Violation; type Error = Violation;
type Namespace = Namespace; type Property = Property;
type PropertyRequest = Property; //@FIXME
fn namespaces() -> &'static [(&'static str, &'static str)] {
return &[ ("D", "DAV:"), ("C", "urn:ietf:params:xml:ns:caldav") ][..]
}
fn short_ns(ns: Self::Namespace) -> &'static str {
match ns {
Namespace::Dav => "D",
Namespace::CalDav => "C",
}
}
} }
pub enum Violation { pub enum Violation {
@ -39,3 +25,9 @@ pub enum Violation {
/// param-filter*)> /// param-filter*)>
SupportedFilter, SupportedFilter,
} }
pub enum Property {
CalendarDescription,
CalendarTimezone,
}

View file

@ -149,16 +149,68 @@ impl<E: Extension, C: Context<E>> QuickWritable<E,C> for ResponseDescription {
impl<E: Extension, C: Context<E>> QuickWritable<E,C> for Location { impl<E: Extension, C: Context<E>> QuickWritable<E,C> for Location {
async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> { async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> {
unimplemented!(); let start = ctx.create_dav_element("location");
let end = start.to_end();
xml.write_event_async(Event::Start(start.clone())).await?;
self.0.write(xml, ctx.child()).await?;
xml.write_event_async(Event::End(end)).await?;
Ok(())
} }
} }
impl<E: Extension, C: Context<E>> QuickWritable<E,C> for PropStat<E> { impl<E: Extension, C: Context<E>> QuickWritable<E,C> for PropStat<E> {
async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> { async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> {
unimplemented!(); let start = ctx.create_dav_element("propstat");
let end = start.to_end();
xml.write_event_async(Event::Start(start.clone())).await?;
self.prop.write(xml, ctx.child()).await?;
self.status.write(xml, ctx.child()).await?;
if let Some(error) = &self.error {
error.write(xml, ctx.child()).await?;
}
if let Some(description) = &self.responsedescription {
description.write(xml, ctx.child()).await?;
}
xml.write_event_async(Event::End(end)).await?;
Ok(())
} }
} }
impl<E: Extension, C: Context<E>> QuickWritable<E,C> for Prop<E> {
async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> {
let start = ctx.create_dav_element("prop");
let end = start.to_end();
xml.write_event_async(Event::Start(start.clone())).await?;
for property in &self.0 {
property.write(xml, ctx.child()).await?;
}
xml.write_event_async(Event::End(end)).await?;
Ok(())
}
}
impl<E: Extension, C: Context<E>> QuickWritable<E,C> for Property<E> {
async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> {
use Property::*;
match self {
CreationDate(date) => unimplemented!(),
DisplayName(name) => unimplemented!(),
//@FIXME not finished
_ => unimplemented!(),
};
Ok(())
}
}
impl<E: Extension, C: Context<E>> QuickWritable<E,C> for Error<E> { impl<E: Extension, C: Context<E>> QuickWritable<E,C> for Error<E> {
async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> { async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> {
let start = ctx.create_dav_element("error"); let start = ctx.create_dav_element("error");

View file

@ -6,10 +6,8 @@ use chrono::{DateTime,FixedOffset};
pub struct Disabled(()); pub struct Disabled(());
pub trait Extension { pub trait Extension {
type Error; type Error;
type Namespace; type Property;
type PropertyRequest;
fn namespaces() -> &'static [(&'static str, &'static str)];
fn short_ns(ns: Self::Namespace) -> &'static str;
} }
/// No extension /// No extension
@ -19,15 +17,8 @@ pub enum Namespace {
} }
impl Extension for NoExtension { impl Extension for NoExtension {
type Error = Disabled; type Error = Disabled;
type Namespace = Namespace; type Property = Disabled;
type PropertyRequest = Disabled;
fn namespaces() -> &'static [(&'static str, &'static str)] {
return &[ ("D", "DAV:") ][..]
}
fn short_ns(ns: Self::Namespace) -> &'static str {
"D"
}
} }
/// 14.1. activelock XML Element /// 14.1. activelock XML Element
@ -38,11 +29,11 @@ impl Extension for NoExtension {
/// <!ELEMENT activelock (lockscope, locktype, depth, owner?, timeout?, /// <!ELEMENT activelock (lockscope, locktype, depth, owner?, timeout?,
/// locktoken?, lockroot)> /// locktoken?, lockroot)>
pub struct ActiveLock { pub struct ActiveLock {
lockscope: LockScope, pub lockscope: LockScope,
locktype: LockType, pub locktype: LockType,
depth: Depth, pub depth: Depth,
owner: Option<Owner>, pub owner: Option<Owner>,
timeout: Option<Timeout>, pub timeout: Option<Timeout>,
} }
/// 14.2 allprop XML Element /// 14.2 allprop XML Element
@ -225,7 +216,7 @@ pub struct Href(pub String);
/// standards. This element MUST NOT contain text or mixed content. /// standards. This element MUST NOT contain text or mixed content.
/// ///
/// <!ELEMENT include ANY > /// <!ELEMENT include ANY >
pub struct Include(Vec<Property>); pub struct Include<T: Extension>(pub Vec<Property<T>>);
/// 14.9. location XML Element /// 14.9. location XML Element
/// ///
@ -241,7 +232,7 @@ pub struct Include(Vec<Property>);
/// that would be used in a Location header. /// that would be used in a Location header.
/// ///
/// <!ELEMENT location (href)> /// <!ELEMENT location (href)>
pub struct Location(Href); pub struct Location(pub Href);
/// 14.10. lockentry XML Element /// 14.10. lockentry XML Element
/// ///
@ -252,8 +243,8 @@ pub struct Location(Href);
/// ///
/// <!ELEMENT lockentry (lockscope, locktype) > /// <!ELEMENT lockentry (lockscope, locktype) >
pub struct LockEntry { pub struct LockEntry {
lokscope: LockScope, pub lokscope: LockScope,
locktype: LockType, pub locktype: LockType,
} }
/// 14.11. lockinfo XML Element /// 14.11. lockinfo XML Element
@ -265,9 +256,9 @@ pub struct LockEntry {
/// ///
/// <!ELEMENT lockinfo (lockscope, locktype, owner?) > /// <!ELEMENT lockinfo (lockscope, locktype, owner?) >
pub struct LockInfo { pub struct LockInfo {
lockscope: LockScope, pub lockscope: LockScope,
locktype: LockType, pub locktype: LockType,
owner: Option<Owner>, pub owner: Option<Owner>,
} }
/// 14.12. lockroot XML Element /// 14.12. lockroot XML Element
@ -282,7 +273,7 @@ pub struct LockInfo {
/// values and the response to LOCK requests. /// values and the response to LOCK requests.
/// ///
/// <!ELEMENT lockroot (href) > /// <!ELEMENT lockroot (href) >
pub struct LockRoot(Href); pub struct LockRoot(pub Href);
/// 14.13. lockscope XML Element /// 14.13. lockscope XML Element
/// ///
@ -369,7 +360,7 @@ pub struct Multistatus<T: Extension> {
/// text content or attributes. /// text content or attributes.
/// ///
/// <!ELEMENT owner ANY > /// <!ELEMENT owner ANY >
pub struct Owner(String); pub struct Owner(pub String);
/// 14.18. prop XML Element /// 14.18. prop XML Element
/// ///
@ -385,7 +376,7 @@ pub struct Owner(String);
/// text or mixed content. /// text or mixed content.
/// ///
/// <!ELEMENT prop ANY > /// <!ELEMENT prop ANY >
pub struct Prop(Vec<Property>); pub struct Prop<T: Extension>(pub Vec<Property<T>>);
/// 14.19. propertyupdate XML Element /// 14.19. propertyupdate XML Element
/// ///
@ -397,10 +388,10 @@ pub struct Prop(Vec<Property>);
/// required to modify the properties on the resource. /// required to modify the properties on the resource.
/// ///
/// <!ELEMENT propertyupdate (remove | set)+ > /// <!ELEMENT propertyupdate (remove | set)+ >
pub struct PropertyUpdate(Vec<PropertyUpdateItem>); pub struct PropertyUpdate<T: Extension>(Vec<PropertyUpdateItem<T>>);
pub enum PropertyUpdateItem { pub enum PropertyUpdateItem<T: Extension> {
Remove(Remove), Remove(Remove<T>),
Set(Set), Set(Set<T>),
} }
/// 14.20. propfind XML Element /// 14.20. propfind XML Element
@ -414,10 +405,10 @@ pub enum PropertyUpdateItem {
/// values. /// values.
/// ///
/// <!ELEMENT propfind ( propname | (allprop, include?) | prop ) > /// <!ELEMENT propfind ( propname | (allprop, include?) | prop ) >
pub enum PropFind { pub enum PropFind<T: Extension> {
PropName(PropName), PropName(PropName),
AllProp(AllProp, Option<Include>), AllProp(AllProp, Option<Include<T>>),
Prop(Prop), Prop(Prop<T>),
} }
/// 14.21. propname XML Element /// 14.21. propname XML Element
@ -446,10 +437,10 @@ pub struct PropName {}
/// ///
/// <!ELEMENT propstat (prop, status, error?, responsedescription?) > /// <!ELEMENT propstat (prop, status, error?, responsedescription?) >
pub struct PropStat<T: Extension> { pub struct PropStat<T: Extension> {
prop: Prop, pub prop: Prop<T>,
status: Status, pub status: Status,
error: Option<Error<T>>, pub error: Option<Error<T>>,
responsedescription: Option<ResponseDescription>, pub responsedescription: Option<ResponseDescription>,
} }
/// 14.23. remove XML Element /// 14.23. remove XML Element
@ -465,7 +456,7 @@ pub struct PropStat<T: Extension> {
/// the names of properties to be removed are required. /// the names of properties to be removed are required.
/// ///
/// <!ELEMENT remove (prop) > /// <!ELEMENT remove (prop) >
pub struct Remove(Prop); pub struct Remove<T: Extension>(pub Prop<T>);
/// 14.24. response XML Element /// 14.24. response XML Element
/// ///
@ -530,7 +521,7 @@ pub struct ResponseDescription(pub String);
/// property, and MUST be subsequently retrievable using PROPFIND. /// property, and MUST be subsequently retrievable using PROPFIND.
/// ///
/// <!ELEMENT set (prop) > /// <!ELEMENT set (prop) >
pub struct Set(Prop); pub struct Set<T: Extension>(pub Prop<T>);
/// 14.27. shared XML Element /// 14.27. shared XML Element
/// ///
@ -595,7 +586,7 @@ pub struct Timeout(u64);
/// the header value could include LWS as defined in [RFC2616], Section /// the header value could include LWS as defined in [RFC2616], Section
/// 4.2. Server implementors SHOULD strip LWS from these values before /// 4.2. Server implementors SHOULD strip LWS from these values before
/// using as WebDAV property values. /// using as WebDAV property values.
pub enum PropertyRequest { pub enum PropertyRequest<T: Extension> {
CreationDate, CreationDate,
DisplayName, DisplayName,
GetContentLanguage, GetContentLanguage,
@ -606,8 +597,9 @@ pub enum PropertyRequest {
LockDiscovery, LockDiscovery,
ResourceType, ResourceType,
SupportedLock, SupportedLock,
Extension(T::PropertyRequest),
} }
pub enum Property { pub enum Property<T: Extension> {
/// 15.1. creationdate Property /// 15.1. creationdate Property
/// ///
/// Name: creationdate /// Name: creationdate
@ -884,6 +876,9 @@ pub enum Property {
/// ///
/// <!ELEMENT supportedlock (lockentry)* > /// <!ELEMENT supportedlock (lockentry)* >
SupportedLock(Vec<LockEntry>), SupportedLock(Vec<LockEntry>),
/// Any extension
Extension(T::Property),
} }