Fix typing of Response
This commit is contained in:
parent
96a27d7b22
commit
ce2fa5c3bc
4 changed files with 115 additions and 49 deletions
|
@ -813,8 +813,9 @@ mod tests {
|
|||
&dav::Multistatus::<Calendar> {
|
||||
responses: vec![
|
||||
dav::Response {
|
||||
href: dav::Href("http://cal.example.com/bernard/work/abcd2.ics".into()),
|
||||
status_or_propstat: dav::StatusOrPropstat::PropStat(vec![dav::PropStat {
|
||||
status_or_propstat: dav::StatusOrPropstat::PropStat(
|
||||
dav::Href("http://cal.example.com/bernard/work/abcd2.ics".into()),
|
||||
vec![dav::PropStat {
|
||||
prop: dav::AnyProp::Value(dav::PropValue(vec![
|
||||
dav::Property::GetEtag("\"fffff-abcd2\"".into()),
|
||||
dav::Property::Extension(Property::CalendarData(CalendarDataPayload {
|
||||
|
@ -825,14 +826,16 @@ mod tests {
|
|||
status: dav::Status(http::status::StatusCode::OK),
|
||||
error: None,
|
||||
responsedescription: None,
|
||||
}]),
|
||||
}]
|
||||
),
|
||||
location: None,
|
||||
error: None,
|
||||
responsedescription: None,
|
||||
},
|
||||
dav::Response {
|
||||
href: dav::Href("http://cal.example.com/bernard/work/abcd3.ics".into()),
|
||||
status_or_propstat: dav::StatusOrPropstat::PropStat(vec![dav::PropStat {
|
||||
status_or_propstat: dav::StatusOrPropstat::PropStat(
|
||||
dav::Href("http://cal.example.com/bernard/work/abcd3.ics".into()),
|
||||
vec![dav::PropStat {
|
||||
prop: dav::AnyProp::Value(dav::PropValue(vec![
|
||||
dav::Property::GetEtag("\"fffff-abcd3\"".into()),
|
||||
dav::Property::Extension(Property::CalendarData(CalendarDataPayload{
|
||||
|
@ -843,7 +846,8 @@ mod tests {
|
|||
status: dav::Status(http::status::StatusCode::OK),
|
||||
error: None,
|
||||
responsedescription: None,
|
||||
}]),
|
||||
}]
|
||||
),
|
||||
location: None,
|
||||
error: None,
|
||||
responsedescription: None,
|
||||
|
|
|
@ -84,7 +84,29 @@ impl<E: Extension> QRead<PropertyUpdate<E>> for PropertyUpdate<E> {
|
|||
}
|
||||
|
||||
/// Generic response
|
||||
//@TODO Multistatus
|
||||
impl<E: Extension> QRead<Multistatus<E>> for Multistatus<E> {
|
||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||
xml.tag_start(DAV_URN, "multistatus").await?;
|
||||
let mut responses = Vec::new();
|
||||
let mut responsedescription = None;
|
||||
|
||||
loop {
|
||||
if let Some(v) = Response::qread(xml).await? {
|
||||
responses.push(v);
|
||||
} else if let Some(v) = ResponseDescription::qread(xml).await? {
|
||||
responsedescription = Some(v);
|
||||
} else {
|
||||
match xml.peek() {
|
||||
Event::End(_) => break,
|
||||
_ => xml.skip().await?,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
xml.tag_stop(DAV_URN, "multistatus").await?;
|
||||
Ok(Some(Multistatus { responses, responsedescription }))
|
||||
}
|
||||
}
|
||||
|
||||
// LOCK REQUEST
|
||||
impl QRead<LockInfo> for LockInfo {
|
||||
|
@ -159,6 +181,27 @@ impl<E: Extension> QRead<Error<E>> for Error<E> {
|
|||
|
||||
|
||||
// ---- INNER XML
|
||||
impl<E: Extension> QRead<Response<E>> for Response<E> {
|
||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||
if xml.maybe_tag_start(DAV_URN, "response").await?.is_none() {
|
||||
return Ok(None)
|
||||
}
|
||||
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl QRead<ResponseDescription> for ResponseDescription {
|
||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||
if xml.maybe_tag_start(DAV_URN, "responsedescription").await?.is_none() {
|
||||
return Ok(None)
|
||||
}
|
||||
let cnt = xml.tag_string().await?;
|
||||
xml.tag_stop(DAV_URN, "responsedescription").await?;
|
||||
Ok(Some(ResponseDescription(cnt)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Extension> QRead<PropertyUpdateItem<E>> for PropertyUpdateItem<E> {
|
||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||
if let Some(rm) = Remove::qread(xml).await? {
|
||||
|
|
|
@ -186,7 +186,6 @@ impl<E: Extension> QWrite for Response<E> {
|
|||
let end = start.to_end();
|
||||
|
||||
xml.q.write_event_async(Event::Start(start.clone())).await?;
|
||||
self.href.qwrite(xml).await?;
|
||||
self.status_or_propstat.qwrite(xml).await?;
|
||||
if let Some(error) = &self.error {
|
||||
error.qwrite(xml).await?;
|
||||
|
@ -204,8 +203,14 @@ impl<E: Extension> QWrite for Response<E> {
|
|||
impl<E: Extension> QWrite for StatusOrPropstat<E> {
|
||||
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||
match self {
|
||||
Self::Status(status) => status.qwrite(xml).await,
|
||||
Self::PropStat(propstat_list) => {
|
||||
Self::Status(many_href, status) => {
|
||||
for href in many_href.iter() {
|
||||
href.qwrite(xml).await?;
|
||||
}
|
||||
status.qwrite(xml).await
|
||||
},
|
||||
Self::PropStat(href, propstat_list) => {
|
||||
href.qwrite(xml).await?;
|
||||
for propstat in propstat_list.iter() {
|
||||
propstat.qwrite(xml).await?;
|
||||
}
|
||||
|
@ -728,39 +733,43 @@ mod tests {
|
|||
&Multistatus::<Core> {
|
||||
responses: vec![
|
||||
Response {
|
||||
href: Href("http://www.example.com/container/".into()),
|
||||
status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat {
|
||||
prop: AnyProp::Name(PropName(vec![
|
||||
PropertyRequest::CreationDate,
|
||||
PropertyRequest::DisplayName,
|
||||
PropertyRequest::ResourceType,
|
||||
PropertyRequest::SupportedLock,
|
||||
])),
|
||||
status: Status(http::status::StatusCode::OK),
|
||||
error: None,
|
||||
responsedescription: None,
|
||||
}]),
|
||||
status_or_propstat: StatusOrPropstat::PropStat(
|
||||
Href("http://www.example.com/container/".into()),
|
||||
vec![PropStat {
|
||||
prop: AnyProp::Name(PropName(vec![
|
||||
PropertyRequest::CreationDate,
|
||||
PropertyRequest::DisplayName,
|
||||
PropertyRequest::ResourceType,
|
||||
PropertyRequest::SupportedLock,
|
||||
])),
|
||||
status: Status(http::status::StatusCode::OK),
|
||||
error: None,
|
||||
responsedescription: None,
|
||||
}]
|
||||
),
|
||||
error: None,
|
||||
responsedescription: None,
|
||||
location: None,
|
||||
},
|
||||
Response {
|
||||
href: Href("http://www.example.com/container/front.html".into()),
|
||||
status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat {
|
||||
prop: AnyProp::Name(PropName(vec![
|
||||
PropertyRequest::CreationDate,
|
||||
PropertyRequest::DisplayName,
|
||||
PropertyRequest::GetContentLength,
|
||||
PropertyRequest::GetContentType,
|
||||
PropertyRequest::GetEtag,
|
||||
PropertyRequest::GetLastModified,
|
||||
PropertyRequest::ResourceType,
|
||||
PropertyRequest::SupportedLock,
|
||||
])),
|
||||
status: Status(http::status::StatusCode::OK),
|
||||
error: None,
|
||||
responsedescription: None,
|
||||
}]),
|
||||
status_or_propstat: StatusOrPropstat::PropStat(
|
||||
Href("http://www.example.com/container/front.html".into()),
|
||||
vec![PropStat {
|
||||
prop: AnyProp::Name(PropName(vec![
|
||||
PropertyRequest::CreationDate,
|
||||
PropertyRequest::DisplayName,
|
||||
PropertyRequest::GetContentLength,
|
||||
PropertyRequest::GetContentType,
|
||||
PropertyRequest::GetEtag,
|
||||
PropertyRequest::GetLastModified,
|
||||
PropertyRequest::ResourceType,
|
||||
PropertyRequest::SupportedLock,
|
||||
])),
|
||||
status: Status(http::status::StatusCode::OK),
|
||||
error: None,
|
||||
responsedescription: None,
|
||||
}
|
||||
]),
|
||||
error: None,
|
||||
responsedescription: None,
|
||||
location: None,
|
||||
|
@ -825,8 +834,9 @@ mod tests {
|
|||
&Multistatus::<Core> {
|
||||
responses: vec![
|
||||
Response {
|
||||
href: Href("/container/".into()),
|
||||
status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat {
|
||||
status_or_propstat: StatusOrPropstat::PropStat(
|
||||
Href("/container/".into()),
|
||||
vec![PropStat {
|
||||
prop: AnyProp::Value(PropValue(vec![
|
||||
Property::CreationDate(FixedOffset::west_opt(8 * 3600)
|
||||
.unwrap()
|
||||
|
@ -848,14 +858,16 @@ mod tests {
|
|||
status: Status(http::status::StatusCode::OK),
|
||||
error: None,
|
||||
responsedescription: None,
|
||||
}]),
|
||||
}]
|
||||
),
|
||||
error: None,
|
||||
responsedescription: None,
|
||||
location: None,
|
||||
},
|
||||
Response {
|
||||
href: Href("/container/front.html".into()),
|
||||
status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat {
|
||||
status_or_propstat: StatusOrPropstat::PropStat(
|
||||
Href("/container/front.html".into()),
|
||||
vec![PropStat {
|
||||
prop: AnyProp::Value(PropValue(vec![
|
||||
Property::CreationDate(FixedOffset::west_opt(8 * 3600)
|
||||
.unwrap()
|
||||
|
@ -884,7 +896,8 @@ mod tests {
|
|||
status: Status(http::status::StatusCode::OK),
|
||||
error: None,
|
||||
responsedescription: None,
|
||||
}]),
|
||||
}]
|
||||
),
|
||||
error: None,
|
||||
responsedescription: None,
|
||||
location: None,
|
||||
|
@ -1018,8 +1031,10 @@ mod tests {
|
|||
let got = serialize(
|
||||
&Multistatus::<Core> {
|
||||
responses: vec![Response {
|
||||
href: Href("http://www.example.com/container/resource3".into()),
|
||||
status_or_propstat: StatusOrPropstat::Status(Status(http::status::StatusCode::from_u16(423).unwrap())),
|
||||
status_or_propstat: StatusOrPropstat::Status(
|
||||
vec![Href("http://www.example.com/container/resource3".into())],
|
||||
Status(http::status::StatusCode::from_u16(423).unwrap())
|
||||
),
|
||||
error: Some(Error(vec![Violation::LockTokenSubmitted(vec![])])),
|
||||
responsedescription: None,
|
||||
location: None,
|
||||
|
|
|
@ -516,15 +516,19 @@ pub struct Remove<E: Extension>(pub PropName<E>);
|
|||
///
|
||||
/// <!ELEMENT response (href, ((href*, status)|(propstat+)),
|
||||
/// error?, responsedescription? , location?) >
|
||||
///
|
||||
/// --- rewritten as ---
|
||||
/// <!ELEMENT response ((href+, status)|(href, propstat+), error?, responsedescription?, location?>
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum StatusOrPropstat<E: Extension> {
|
||||
Status(Status),
|
||||
PropStat(Vec<PropStat<E>>),
|
||||
// One status, multiple hrefs...
|
||||
Status(Vec<Href>, Status),
|
||||
// A single href, multiple properties...
|
||||
PropStat(Href, Vec<PropStat<E>>),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Response<E: Extension> {
|
||||
pub href: Href, // It's wrong according to the spec, but I don't understand why there is an href*
|
||||
pub status_or_propstat: StatusOrPropstat<E>,
|
||||
pub error: Option<Error<E>>,
|
||||
pub responsedescription: Option<ResponseDescription>,
|
||||
|
|
Loading…
Reference in a new issue