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> {
|
&dav::Multistatus::<Calendar> {
|
||||||
responses: vec![
|
responses: vec![
|
||||||
dav::Response {
|
dav::Response {
|
||||||
href: dav::Href("http://cal.example.com/bernard/work/abcd2.ics".into()),
|
status_or_propstat: dav::StatusOrPropstat::PropStat(
|
||||||
status_or_propstat: dav::StatusOrPropstat::PropStat(vec![dav::PropStat {
|
dav::Href("http://cal.example.com/bernard/work/abcd2.ics".into()),
|
||||||
|
vec![dav::PropStat {
|
||||||
prop: dav::AnyProp::Value(dav::PropValue(vec![
|
prop: dav::AnyProp::Value(dav::PropValue(vec![
|
||||||
dav::Property::GetEtag("\"fffff-abcd2\"".into()),
|
dav::Property::GetEtag("\"fffff-abcd2\"".into()),
|
||||||
dav::Property::Extension(Property::CalendarData(CalendarDataPayload {
|
dav::Property::Extension(Property::CalendarData(CalendarDataPayload {
|
||||||
|
@ -825,14 +826,16 @@ mod tests {
|
||||||
status: dav::Status(http::status::StatusCode::OK),
|
status: dav::Status(http::status::StatusCode::OK),
|
||||||
error: None,
|
error: None,
|
||||||
responsedescription: None,
|
responsedescription: None,
|
||||||
}]),
|
}]
|
||||||
|
),
|
||||||
location: None,
|
location: None,
|
||||||
error: None,
|
error: None,
|
||||||
responsedescription: None,
|
responsedescription: None,
|
||||||
},
|
},
|
||||||
dav::Response {
|
dav::Response {
|
||||||
href: dav::Href("http://cal.example.com/bernard/work/abcd3.ics".into()),
|
status_or_propstat: dav::StatusOrPropstat::PropStat(
|
||||||
status_or_propstat: dav::StatusOrPropstat::PropStat(vec![dav::PropStat {
|
dav::Href("http://cal.example.com/bernard/work/abcd3.ics".into()),
|
||||||
|
vec![dav::PropStat {
|
||||||
prop: dav::AnyProp::Value(dav::PropValue(vec![
|
prop: dav::AnyProp::Value(dav::PropValue(vec![
|
||||||
dav::Property::GetEtag("\"fffff-abcd3\"".into()),
|
dav::Property::GetEtag("\"fffff-abcd3\"".into()),
|
||||||
dav::Property::Extension(Property::CalendarData(CalendarDataPayload{
|
dav::Property::Extension(Property::CalendarData(CalendarDataPayload{
|
||||||
|
@ -843,7 +846,8 @@ mod tests {
|
||||||
status: dav::Status(http::status::StatusCode::OK),
|
status: dav::Status(http::status::StatusCode::OK),
|
||||||
error: None,
|
error: None,
|
||||||
responsedescription: None,
|
responsedescription: None,
|
||||||
}]),
|
}]
|
||||||
|
),
|
||||||
location: None,
|
location: None,
|
||||||
error: None,
|
error: None,
|
||||||
responsedescription: None,
|
responsedescription: None,
|
||||||
|
|
|
@ -84,7 +84,29 @@ impl<E: Extension> QRead<PropertyUpdate<E>> for PropertyUpdate<E> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generic response
|
/// 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
|
// LOCK REQUEST
|
||||||
impl QRead<LockInfo> for LockInfo {
|
impl QRead<LockInfo> for LockInfo {
|
||||||
|
@ -159,6 +181,27 @@ impl<E: Extension> QRead<Error<E>> for Error<E> {
|
||||||
|
|
||||||
|
|
||||||
// ---- INNER XML
|
// ---- 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> {
|
impl<E: Extension> QRead<PropertyUpdateItem<E>> for PropertyUpdateItem<E> {
|
||||||
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
async fn qread(xml: &mut Reader<impl IRead>) -> Result<Option<Self>, ParsingError> {
|
||||||
if let Some(rm) = Remove::qread(xml).await? {
|
if let Some(rm) = Remove::qread(xml).await? {
|
||||||
|
|
|
@ -186,7 +186,6 @@ impl<E: Extension> QWrite for Response<E> {
|
||||||
let end = start.to_end();
|
let end = start.to_end();
|
||||||
|
|
||||||
xml.q.write_event_async(Event::Start(start.clone())).await?;
|
xml.q.write_event_async(Event::Start(start.clone())).await?;
|
||||||
self.href.qwrite(xml).await?;
|
|
||||||
self.status_or_propstat.qwrite(xml).await?;
|
self.status_or_propstat.qwrite(xml).await?;
|
||||||
if let Some(error) = &self.error {
|
if let Some(error) = &self.error {
|
||||||
error.qwrite(xml).await?;
|
error.qwrite(xml).await?;
|
||||||
|
@ -204,8 +203,14 @@ impl<E: Extension> QWrite for Response<E> {
|
||||||
impl<E: Extension> QWrite for StatusOrPropstat<E> {
|
impl<E: Extension> QWrite for StatusOrPropstat<E> {
|
||||||
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
async fn qwrite(&self, xml: &mut Writer<impl IWrite>) -> Result<(), QError> {
|
||||||
match self {
|
match self {
|
||||||
Self::Status(status) => status.qwrite(xml).await,
|
Self::Status(many_href, status) => {
|
||||||
Self::PropStat(propstat_list) => {
|
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() {
|
for propstat in propstat_list.iter() {
|
||||||
propstat.qwrite(xml).await?;
|
propstat.qwrite(xml).await?;
|
||||||
}
|
}
|
||||||
|
@ -728,39 +733,43 @@ mod tests {
|
||||||
&Multistatus::<Core> {
|
&Multistatus::<Core> {
|
||||||
responses: vec![
|
responses: vec![
|
||||||
Response {
|
Response {
|
||||||
href: Href("http://www.example.com/container/".into()),
|
status_or_propstat: StatusOrPropstat::PropStat(
|
||||||
status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat {
|
Href("http://www.example.com/container/".into()),
|
||||||
prop: AnyProp::Name(PropName(vec![
|
vec![PropStat {
|
||||||
PropertyRequest::CreationDate,
|
prop: AnyProp::Name(PropName(vec![
|
||||||
PropertyRequest::DisplayName,
|
PropertyRequest::CreationDate,
|
||||||
PropertyRequest::ResourceType,
|
PropertyRequest::DisplayName,
|
||||||
PropertyRequest::SupportedLock,
|
PropertyRequest::ResourceType,
|
||||||
])),
|
PropertyRequest::SupportedLock,
|
||||||
status: Status(http::status::StatusCode::OK),
|
])),
|
||||||
error: None,
|
status: Status(http::status::StatusCode::OK),
|
||||||
responsedescription: None,
|
error: None,
|
||||||
}]),
|
responsedescription: None,
|
||||||
|
}]
|
||||||
|
),
|
||||||
error: None,
|
error: None,
|
||||||
responsedescription: None,
|
responsedescription: None,
|
||||||
location: None,
|
location: None,
|
||||||
},
|
},
|
||||||
Response {
|
Response {
|
||||||
href: Href("http://www.example.com/container/front.html".into()),
|
status_or_propstat: StatusOrPropstat::PropStat(
|
||||||
status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat {
|
Href("http://www.example.com/container/front.html".into()),
|
||||||
prop: AnyProp::Name(PropName(vec![
|
vec![PropStat {
|
||||||
PropertyRequest::CreationDate,
|
prop: AnyProp::Name(PropName(vec![
|
||||||
PropertyRequest::DisplayName,
|
PropertyRequest::CreationDate,
|
||||||
PropertyRequest::GetContentLength,
|
PropertyRequest::DisplayName,
|
||||||
PropertyRequest::GetContentType,
|
PropertyRequest::GetContentLength,
|
||||||
PropertyRequest::GetEtag,
|
PropertyRequest::GetContentType,
|
||||||
PropertyRequest::GetLastModified,
|
PropertyRequest::GetEtag,
|
||||||
PropertyRequest::ResourceType,
|
PropertyRequest::GetLastModified,
|
||||||
PropertyRequest::SupportedLock,
|
PropertyRequest::ResourceType,
|
||||||
])),
|
PropertyRequest::SupportedLock,
|
||||||
status: Status(http::status::StatusCode::OK),
|
])),
|
||||||
error: None,
|
status: Status(http::status::StatusCode::OK),
|
||||||
responsedescription: None,
|
error: None,
|
||||||
}]),
|
responsedescription: None,
|
||||||
|
}
|
||||||
|
]),
|
||||||
error: None,
|
error: None,
|
||||||
responsedescription: None,
|
responsedescription: None,
|
||||||
location: None,
|
location: None,
|
||||||
|
@ -825,8 +834,9 @@ mod tests {
|
||||||
&Multistatus::<Core> {
|
&Multistatus::<Core> {
|
||||||
responses: vec![
|
responses: vec![
|
||||||
Response {
|
Response {
|
||||||
href: Href("/container/".into()),
|
status_or_propstat: StatusOrPropstat::PropStat(
|
||||||
status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat {
|
Href("/container/".into()),
|
||||||
|
vec![PropStat {
|
||||||
prop: AnyProp::Value(PropValue(vec![
|
prop: AnyProp::Value(PropValue(vec![
|
||||||
Property::CreationDate(FixedOffset::west_opt(8 * 3600)
|
Property::CreationDate(FixedOffset::west_opt(8 * 3600)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -848,14 +858,16 @@ mod tests {
|
||||||
status: Status(http::status::StatusCode::OK),
|
status: Status(http::status::StatusCode::OK),
|
||||||
error: None,
|
error: None,
|
||||||
responsedescription: None,
|
responsedescription: None,
|
||||||
}]),
|
}]
|
||||||
|
),
|
||||||
error: None,
|
error: None,
|
||||||
responsedescription: None,
|
responsedescription: None,
|
||||||
location: None,
|
location: None,
|
||||||
},
|
},
|
||||||
Response {
|
Response {
|
||||||
href: Href("/container/front.html".into()),
|
status_or_propstat: StatusOrPropstat::PropStat(
|
||||||
status_or_propstat: StatusOrPropstat::PropStat(vec![PropStat {
|
Href("/container/front.html".into()),
|
||||||
|
vec![PropStat {
|
||||||
prop: AnyProp::Value(PropValue(vec![
|
prop: AnyProp::Value(PropValue(vec![
|
||||||
Property::CreationDate(FixedOffset::west_opt(8 * 3600)
|
Property::CreationDate(FixedOffset::west_opt(8 * 3600)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -884,7 +896,8 @@ mod tests {
|
||||||
status: Status(http::status::StatusCode::OK),
|
status: Status(http::status::StatusCode::OK),
|
||||||
error: None,
|
error: None,
|
||||||
responsedescription: None,
|
responsedescription: None,
|
||||||
}]),
|
}]
|
||||||
|
),
|
||||||
error: None,
|
error: None,
|
||||||
responsedescription: None,
|
responsedescription: None,
|
||||||
location: None,
|
location: None,
|
||||||
|
@ -1018,8 +1031,10 @@ mod tests {
|
||||||
let got = serialize(
|
let got = serialize(
|
||||||
&Multistatus::<Core> {
|
&Multistatus::<Core> {
|
||||||
responses: vec![Response {
|
responses: vec![Response {
|
||||||
href: Href("http://www.example.com/container/resource3".into()),
|
status_or_propstat: StatusOrPropstat::Status(
|
||||||
status_or_propstat: StatusOrPropstat::Status(Status(http::status::StatusCode::from_u16(423).unwrap())),
|
vec![Href("http://www.example.com/container/resource3".into())],
|
||||||
|
Status(http::status::StatusCode::from_u16(423).unwrap())
|
||||||
|
),
|
||||||
error: Some(Error(vec![Violation::LockTokenSubmitted(vec![])])),
|
error: Some(Error(vec![Violation::LockTokenSubmitted(vec![])])),
|
||||||
responsedescription: None,
|
responsedescription: None,
|
||||||
location: None,
|
location: None,
|
||||||
|
|
|
@ -516,15 +516,19 @@ pub struct Remove<E: Extension>(pub PropName<E>);
|
||||||
///
|
///
|
||||||
/// <!ELEMENT response (href, ((href*, status)|(propstat+)),
|
/// <!ELEMENT response (href, ((href*, status)|(propstat+)),
|
||||||
/// error?, responsedescription? , location?) >
|
/// error?, responsedescription? , location?) >
|
||||||
|
///
|
||||||
|
/// --- rewritten as ---
|
||||||
|
/// <!ELEMENT response ((href+, status)|(href, propstat+), error?, responsedescription?, location?>
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum StatusOrPropstat<E: Extension> {
|
pub enum StatusOrPropstat<E: Extension> {
|
||||||
Status(Status),
|
// One status, multiple hrefs...
|
||||||
PropStat(Vec<PropStat<E>>),
|
Status(Vec<Href>, Status),
|
||||||
|
// A single href, multiple properties...
|
||||||
|
PropStat(Href, Vec<PropStat<E>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Response<E: Extension> {
|
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 status_or_propstat: StatusOrPropstat<E>,
|
||||||
pub error: Option<Error<E>>,
|
pub error: Option<Error<E>>,
|
||||||
pub responsedescription: Option<ResponseDescription>,
|
pub responsedescription: Option<ResponseDescription>,
|
||||||
|
|
Loading…
Reference in a new issue