mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-14 02:22:21 +00:00
PROPFIND: Implement propname, altough in an ugly way
This commit is contained in:
@@ -55,11 +55,18 @@ pub trait ResourceService: Sized {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct PropWrapper<T: Serialize> {
|
pub struct PropTagWrapper<T: Serialize> {
|
||||||
#[serde(rename = "$value")]
|
#[serde(rename = "$value")]
|
||||||
prop: T,
|
prop: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum PropWrapper<T: Serialize> {
|
||||||
|
Prop(PropTagWrapper<T>),
|
||||||
|
TagList(TagList),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub struct PropstatElement<T: Serialize> {
|
pub struct PropstatElement<T: Serialize> {
|
||||||
@@ -104,11 +111,20 @@ impl<R: Resource> HandlePropfind for R {
|
|||||||
if props.len() != 1 {
|
if props.len() != 1 {
|
||||||
// propname MUST be the only queried prop per spec
|
// propname MUST be the only queried prop per spec
|
||||||
return Err(
|
return Err(
|
||||||
Error::BadRequest("allprop MUST be the only queried prop".to_owned()).into(),
|
Error::BadRequest("propname MUST be the only queried prop".to_owned()).into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// TODO: implement propname
|
let props: Vec<String> = R::list_props()
|
||||||
props = R::list_props().into();
|
.iter()
|
||||||
|
.map(|&prop| prop.to_string())
|
||||||
|
.collect();
|
||||||
|
return Ok(PropstatResponseElement {
|
||||||
|
href: self.get_path().to_owned(),
|
||||||
|
propstat: vec![PropstatType::Normal(PropstatElement {
|
||||||
|
prop: PropWrapper::TagList(TagList::from(props)),
|
||||||
|
status: format!("HTTP/1.1 {}", StatusCode::OK),
|
||||||
|
})],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if props.contains(&"allprop") {
|
if props.contains(&"allprop") {
|
||||||
if props.len() != 1 {
|
if props.len() != 1 {
|
||||||
@@ -120,22 +136,29 @@ impl<R: Resource> HandlePropfind for R {
|
|||||||
props = R::list_props().into();
|
props = R::list_props().into();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut invalid_props = Vec::new();
|
let (valid_props, invalid_props): (Vec<Option<R::PropName>>, Vec<Option<&str>>) = props
|
||||||
let mut prop_responses = Vec::new();
|
.into_iter()
|
||||||
for prop in props {
|
.map(|prop| {
|
||||||
if let Ok(valid_prop) = R::PropName::from_str(prop) {
|
if let Ok(valid_prop) = R::PropName::from_str(prop) {
|
||||||
let response = self.get_prop(prefix, valid_prop.clone())?;
|
(Some(valid_prop), None)
|
||||||
prop_responses.push(response);
|
} else {
|
||||||
} else {
|
(None, Some(prop))
|
||||||
invalid_props.push(prop);
|
}
|
||||||
}
|
})
|
||||||
}
|
.unzip();
|
||||||
|
let valid_props: Vec<R::PropName> = valid_props.into_iter().flatten().collect();
|
||||||
|
let invalid_props: Vec<&str> = invalid_props.into_iter().flatten().collect();
|
||||||
|
|
||||||
|
let prop_responses = valid_props
|
||||||
|
.into_iter()
|
||||||
|
.map(|prop| self.get_prop(prefix, prop))
|
||||||
|
.collect::<Result<Vec<R::Prop>, R::Error>>()?;
|
||||||
|
|
||||||
let mut propstats = vec![PropstatType::Normal(PropstatElement {
|
let mut propstats = vec![PropstatType::Normal(PropstatElement {
|
||||||
status: format!("HTTP/1.1 {}", StatusCode::OK),
|
status: format!("HTTP/1.1 {}", StatusCode::OK),
|
||||||
prop: PropWrapper {
|
prop: PropWrapper::Prop(PropTagWrapper {
|
||||||
prop: prop_responses,
|
prop: prop_responses,
|
||||||
},
|
}),
|
||||||
})];
|
})];
|
||||||
if !invalid_props.is_empty() {
|
if !invalid_props.is_empty() {
|
||||||
propstats.push(PropstatType::NotFound(PropstatElement {
|
propstats.push(PropstatType::NotFound(PropstatElement {
|
||||||
|
|||||||
Reference in New Issue
Block a user