type refactor on <prop>

This commit is contained in:
Quentin 2024-03-01 17:17:51 +01:00
parent 77e2f8abbb
commit dee970afe5
Signed by: quentin
GPG key ID: E9602264D639FF68
2 changed files with 82 additions and 43 deletions

View file

@ -72,21 +72,20 @@ impl<C: Context> QuickWritable<C> for PropFind<C> {
include.write(xml, ctx.child()).await?; include.write(xml, ctx.child()).await?;
} }
}, },
Self::Prop(many_propreq) => { Self::Prop(propname) => propname.write(xml, ctx.child()).await?,
let start = ctx.create_dav_element("prop");
let end = start.to_end();
xml.write_event_async(Event::Start(start.clone())).await?;
for propreq in many_propreq.iter() {
propreq.write(xml, ctx.child()).await?;
}
xml.write_event_async(Event::End(end)).await?;
},
} }
xml.write_event_async(Event::End(end)).await xml.write_event_async(Event::End(end)).await
} }
} }
/// PROPPATCH REQUEST
impl<C: Context> QuickWritable<C> for PropertyUpdate<C> {
async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> {
unimplemented!();
}
}
/// PROPFIND RESPONSE, PROPPATCH RESPONSE, COPY RESPONSE, MOVE RESPONSE /// PROPFIND RESPONSE, PROPPATCH RESPONSE, COPY RESPONSE, MOVE RESPONSE
/// DELETE RESPONSE, /// DELETE RESPONSE,
impl<C: Context> QuickWritable<C> for Multistatus<C> { impl<C: Context> QuickWritable<C> for Multistatus<C> {
@ -124,31 +123,43 @@ impl<C: Context> QuickWritable<C> for LockInfo {
} }
/// SOME LOCK RESPONSES /// SOME LOCK RESPONSES
impl<C: Context> QuickWritable<C> for Prop<C> { impl<C: Context> QuickWritable<C> for PropValue<C> {
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("prop"); let start = ctx.create_dav_element("prop");
let end = start.to_end(); let end = start.to_end();
xml.write_event_async(Event::Start(start.clone())).await?; xml.write_event_async(Event::Start(start.clone())).await?;
match self { for propval in &self.0 {
Self::Name(many_names) => {
for propname in many_names {
propname.write(xml, ctx.child()).await?;
}
},
Self::Value(many_values) => {
for propval in many_values {
propval.write(xml, ctx.child()).await?; propval.write(xml, ctx.child()).await?;
} }
} xml.write_event_async(Event::End(end)).await
};
xml.write_event_async(Event::End(end)).await?;
Ok(())
} }
} }
// --- XML inner elements // --- XML inner elements
impl<C: Context> QuickWritable<C> for AnyProp<C> {
async fn write(&self, xml: &mut Writer<impl AsyncWrite+Unpin>, ctx: C) -> Result<(), QError> {
match self {
Self::Name(propname) => propname.write(xml, ctx).await,
Self::Value(propval) => propval.write(xml, ctx).await,
}
}
}
impl<C: Context> QuickWritable<C> for PropName<C> {
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 propname in &self.0 {
propname.write(xml, ctx.child()).await?;
}
xml.write_event_async(Event::End(end)).await
}
}
impl<C: Context> QuickWritable<C> for Href { impl<C: Context> QuickWritable<C> for Href {
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("href"); let start = ctx.create_dav_element("href");
@ -411,7 +422,7 @@ impl<C: Context> QuickWritable<C> for Include<C> {
impl<C: Context> QuickWritable<C> for PropertyRequest<C> { impl<C: Context> QuickWritable<C> for PropertyRequest<C> {
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> {
use PropertyRequest::*; use PropertyRequest::*;
let mut atom = (async |c| xml.write_event_async(Event::Empty(ctx.create_dav_element(c))).await); let mut atom = async |c| xml.write_event_async(Event::Empty(ctx.create_dav_element(c))).await;
match self { match self {
CreationDate => atom("creationdate").await, CreationDate => atom("creationdate").await,
@ -724,12 +735,12 @@ mod tests {
Response { Response {
href: Href("http://www.example.com/container/".into()), href: Href("http://www.example.com/container/".into()),
status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat { status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat {
prop: Prop::Name(vec![ prop: AnyProp::Name(PropName(vec![
PropertyRequest::CreationDate, PropertyRequest::CreationDate,
PropertyRequest::DisplayName, PropertyRequest::DisplayName,
PropertyRequest::ResourceType, PropertyRequest::ResourceType,
PropertyRequest::SupportedLock, PropertyRequest::SupportedLock,
]), ])),
status: Status(http::status::StatusCode::OK), status: Status(http::status::StatusCode::OK),
error: None, error: None,
responsedescription: None, responsedescription: None,
@ -741,7 +752,7 @@ mod tests {
Response { Response {
href: Href("http://www.example.com/container/front.html".into()), href: Href("http://www.example.com/container/front.html".into()),
status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat { status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat {
prop: Prop::Name(vec![ prop: AnyProp::Name(PropName(vec![
PropertyRequest::CreationDate, PropertyRequest::CreationDate,
PropertyRequest::DisplayName, PropertyRequest::DisplayName,
PropertyRequest::GetContentLength, PropertyRequest::GetContentLength,
@ -750,7 +761,7 @@ mod tests {
PropertyRequest::GetLastModified, PropertyRequest::GetLastModified,
PropertyRequest::ResourceType, PropertyRequest::ResourceType,
PropertyRequest::SupportedLock, PropertyRequest::SupportedLock,
]), ])),
status: Status(http::status::StatusCode::OK), status: Status(http::status::StatusCode::OK),
error: None, error: None,
responsedescription: None, responsedescription: None,
@ -823,7 +834,7 @@ mod tests {
Response { Response {
href: Href("/container/".into()), href: Href("/container/".into()),
status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat { status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat {
prop: Prop::Value(vec![ prop: AnyProp::Value(PropValue(vec![
Property::CreationDate(FixedOffset::west_opt(8 * 3600) Property::CreationDate(FixedOffset::west_opt(8 * 3600)
.unwrap() .unwrap()
.with_ymd_and_hms(1997, 12, 1, 17, 42, 21) .with_ymd_and_hms(1997, 12, 1, 17, 42, 21)
@ -840,7 +851,7 @@ mod tests {
locktype: LockType::Write, locktype: LockType::Write,
}, },
]), ]),
]), ])),
status: Status(http::status::StatusCode::OK), status: Status(http::status::StatusCode::OK),
error: None, error: None,
responsedescription: None, responsedescription: None,
@ -852,7 +863,7 @@ mod tests {
Response { Response {
href: Href("/container/front.html".into()), href: Href("/container/front.html".into()),
status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat { status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat {
prop: Prop::Value(vec![ prop: AnyProp::Value(PropValue(vec![
Property::CreationDate(FixedOffset::west_opt(8 * 3600) Property::CreationDate(FixedOffset::west_opt(8 * 3600)
.unwrap() .unwrap()
.with_ymd_and_hms(1997, 12, 1, 18, 27, 21) .with_ymd_and_hms(1997, 12, 1, 18, 27, 21)
@ -876,7 +887,7 @@ mod tests {
locktype: LockType::Write, locktype: LockType::Write,
}, },
]), ]),
]), ])),
status: Status(http::status::StatusCode::OK), status: Status(http::status::StatusCode::OK),
error: None, error: None,
responsedescription: None, responsedescription: None,
@ -981,4 +992,30 @@ mod tests {
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n"); assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
} }
#[tokio::test]
async fn rfc_propertyupdate() {
let got = serialize(
NoExtension { root: true },
&PropertyUpdate(vec![
PropertyUpdateItem::Set(Set(PropValue(vec![ ]))),
PropertyUpdateItem::Remove(Remove(PropName(vec![]))),
]),
).await;
let expected = r#"<D:propertyupdate xmlns:D="DAV:">
<D:set>
<D:prop>
<D:getcontentlanguage>fr-FR</D:getcontentlanguage>
</D:prop>
</D:set>
<D:remove>
<D:prop>
<D:displayname/>
</D:prop>
</D:remove>
</D:propertyupdate>"#;
assert_eq!(&got, expected, "\n---GOT---\n{got}\n---EXP---\n{expected}\n");
}
} }

View file

@ -372,10 +372,12 @@ pub struct Owner {
/// text or mixed content. /// text or mixed content.
/// ///
/// <!ELEMENT prop ANY > /// <!ELEMENT prop ANY >
pub enum Prop<T: Extension> { pub enum AnyProp<T: Extension> {
Name(Vec<PropertyRequest<T>>), Name(PropName<T>),
Value(Vec<Property<T>>), Value(PropValue<T>),
} }
pub struct PropName<T: Extension>(pub Vec<PropertyRequest<T>>);
pub struct PropValue<T: Extension>(pub Vec<Property<T>>);
/// 14.19. propertyupdate XML Element /// 14.19. propertyupdate XML Element
/// ///
@ -387,7 +389,7 @@ pub enum Prop<T: Extension> {
/// 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<T: Extension>(Vec<PropertyUpdateItem<T>>); pub struct PropertyUpdate<T: Extension>(pub Vec<PropertyUpdateItem<T>>);
pub enum PropertyUpdateItem<T: Extension> { pub enum PropertyUpdateItem<T: Extension> {
Remove(Remove<T>), Remove(Remove<T>),
Set(Set<T>), Set(Set<T>),
@ -430,7 +432,7 @@ pub enum PropertyUpdateItem<T: Extension> {
pub enum PropFind<T: Extension> { pub enum PropFind<T: Extension> {
PropName, PropName,
AllProp(Option<Include<T>>), AllProp(Option<Include<T>>),
Prop(Vec<PropertyRequest<T>>), Prop(PropName<T>),
} }
@ -451,7 +453,7 @@ pub enum PropFind<T: Extension> {
/// ///
/// <!ELEMENT propstat (prop, status, error?, responsedescription?) > /// <!ELEMENT propstat (prop, status, error?, responsedescription?) >
pub struct PropStat<T: Extension> { pub struct PropStat<T: Extension> {
pub prop: Prop<T>, pub prop: AnyProp<T>,
pub status: Status, pub status: Status,
pub error: Option<Error<T>>, pub error: Option<Error<T>>,
pub responsedescription: Option<ResponseDescription>, pub responsedescription: Option<ResponseDescription>,
@ -470,7 +472,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<T: Extension>(pub Prop<T>); pub struct Remove<T: Extension>(pub PropName<T>);
/// 14.24. response XML Element /// 14.24. response XML Element
/// ///
@ -535,7 +537,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<T: Extension>(pub Prop<T>); pub struct Set<T: Extension>(pub PropValue<T>);
/// 14.27. shared XML Element /// 14.27. shared XML Element
/// ///