mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-14 07:02:24 +00:00
Refactoring
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
pub mod depth_header;
|
||||
pub mod error;
|
||||
pub mod methods;
|
||||
pub mod namespace;
|
||||
pub mod privileges;
|
||||
pub mod resource;
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
pub mod delete;
|
||||
pub mod propfind;
|
||||
pub mod proppatch;
|
||||
|
||||
pub use delete::route_delete;
|
||||
pub use propfind::route_propfind;
|
||||
pub use proppatch::route_proppatch;
|
||||
7
crates/dav/src/resource/methods/mod.rs
Normal file
7
crates/dav/src/resource/methods/mod.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
mod delete;
|
||||
mod propfind;
|
||||
mod proppatch;
|
||||
|
||||
pub(crate) use delete::route_delete;
|
||||
pub(crate) use propfind::route_propfind;
|
||||
pub(crate) use proppatch::route_proppatch;
|
||||
@@ -4,9 +4,9 @@ use crate::resource::CommonPropertiesProp;
|
||||
use crate::resource::EitherProp;
|
||||
use crate::resource::Resource;
|
||||
use crate::resource::ResourceService;
|
||||
use crate::xml::multistatus::PropstatWrapper;
|
||||
use crate::xml::MultistatusElement;
|
||||
use crate::xml::TagList;
|
||||
use crate::xml::PropElement;
|
||||
use crate::xml::PropfindType;
|
||||
use crate::Error;
|
||||
use actix_web::web::Path;
|
||||
use actix_web::HttpRequest;
|
||||
@@ -17,21 +17,7 @@ use tracing_actix_web::RootSpan;
|
||||
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct PropElement {
|
||||
#[serde(flatten)]
|
||||
pub prop: TagList,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum PropfindType {
|
||||
Propname,
|
||||
Allprop,
|
||||
Prop(PropElement),
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct PropfindElement {
|
||||
#[serde(rename = "$value")]
|
||||
prop: PropfindType,
|
||||
@@ -39,7 +25,7 @@ struct PropfindElement {
|
||||
|
||||
#[instrument(parent = root_span.id(), skip(path_components, req, root_span))]
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub async fn route_propfind<R: ResourceService>(
|
||||
pub(crate) async fn route_propfind<R: ResourceService>(
|
||||
path_components: Path<R::PathComponents>,
|
||||
body: String,
|
||||
req: HttpRequest,
|
||||
@@ -48,8 +34,8 @@ pub async fn route_propfind<R: ResourceService>(
|
||||
root_span: RootSpan,
|
||||
) -> Result<
|
||||
MultistatusElement<
|
||||
PropstatWrapper<EitherProp<<R::Resource as Resource>::Prop, CommonPropertiesProp>>,
|
||||
PropstatWrapper<EitherProp<<R::MemberType as Resource>::Prop, CommonPropertiesProp>>,
|
||||
EitherProp<<R::Resource as Resource>::Prop, CommonPropertiesProp>,
|
||||
EitherProp<<R::MemberType as Resource>::Prop, CommonPropertiesProp>,
|
||||
>,
|
||||
R::Error,
|
||||
> {
|
||||
@@ -71,12 +57,8 @@ pub async fn route_propfind<R: ResourceService>(
|
||||
};
|
||||
|
||||
let props = match propfind.prop {
|
||||
PropfindType::Allprop => {
|
||||
vec!["allprop".to_owned()]
|
||||
}
|
||||
PropfindType::Propname => {
|
||||
vec!["propname".to_owned()]
|
||||
}
|
||||
PropfindType::Allprop => vec!["allprop".to_owned()],
|
||||
PropfindType::Propname => vec!["propname".to_owned()],
|
||||
PropfindType::Prop(PropElement { prop: prop_tags }) => prop_tags.into_inner(),
|
||||
};
|
||||
let props: Vec<&str> = props.iter().map(String::as_str).collect();
|
||||
@@ -37,8 +37,8 @@ struct RemovePropertyElement {
|
||||
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
enum Operation<T> {
|
||||
Set(SetPropertyElement<T>),
|
||||
enum Operation<PropType> {
|
||||
Set(SetPropertyElement<PropType>),
|
||||
Remove(RemovePropertyElement),
|
||||
}
|
||||
|
||||
@@ -50,17 +50,18 @@ struct PropertyupdateElement<T> {
|
||||
}
|
||||
|
||||
#[instrument(parent = root_span.id(), skip(path, req, root_span))]
|
||||
pub async fn route_proppatch<R: ResourceService>(
|
||||
pub(crate) async fn route_proppatch<R: ResourceService>(
|
||||
path: Path<R::PathComponents>,
|
||||
body: String,
|
||||
req: HttpRequest,
|
||||
user: User,
|
||||
root_span: RootSpan,
|
||||
) -> Result<MultistatusElement<PropstatWrapper<String>, PropstatWrapper<String>>, R::Error> {
|
||||
) -> Result<MultistatusElement<String, String>, R::Error> {
|
||||
let path_components = path.into_inner();
|
||||
let href = req.path().to_owned();
|
||||
let resource_service = R::new(&req, path_components.clone()).await?;
|
||||
|
||||
// Extract operations
|
||||
let PropertyupdateElement::<<R::Resource as Resource>::Prop> { operations } =
|
||||
quick_xml::de::from_str(&body).map_err(Error::XmlDeserializationError)?;
|
||||
|
||||
@@ -104,34 +105,20 @@ pub async fn route_proppatch<R: ResourceService>(
|
||||
continue;
|
||||
}
|
||||
match resource.set_prop(prop) {
|
||||
Ok(()) => {
|
||||
props_ok.push(propname);
|
||||
}
|
||||
Err(Error::PropReadOnly) => {
|
||||
props_conflict.push(propname);
|
||||
}
|
||||
Err(err) => {
|
||||
return Err(err.into());
|
||||
}
|
||||
}
|
||||
Ok(()) => props_ok.push(propname),
|
||||
Err(Error::PropReadOnly) => props_conflict.push(propname),
|
||||
Err(err) => return Err(err.into()),
|
||||
};
|
||||
}
|
||||
Operation::Remove(_remove_el) => {
|
||||
match <<R::Resource as Resource>::PropName as FromStr>::from_str(&propname) {
|
||||
Ok(prop) => match resource.remove_prop(&prop) {
|
||||
Ok(()) => {
|
||||
props_ok.push(propname);
|
||||
}
|
||||
Err(Error::PropReadOnly) => {
|
||||
props_conflict.push(propname);
|
||||
}
|
||||
Err(err) => {
|
||||
return Err(err.into());
|
||||
}
|
||||
Ok(()) => props_ok.push(propname),
|
||||
Err(Error::PropReadOnly) => props_conflict.push(propname),
|
||||
Err(err) => return Err(err.into()),
|
||||
},
|
||||
Err(_) => {
|
||||
// I guess removing a nonexisting property should be successful :)
|
||||
props_ok.push(propname);
|
||||
}
|
||||
// I guess removing a nonexisting property should be successful :)
|
||||
Err(_) => props_ok.push(propname),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ use std::str::FromStr;
|
||||
use strum::{EnumString, VariantNames};
|
||||
|
||||
mod invalid_property;
|
||||
mod methods;
|
||||
mod resource_service;
|
||||
|
||||
pub trait ResourceProp: InvalidProperty + Serialize + for<'de> Deserialize<'de> {}
|
||||
@@ -149,10 +150,7 @@ pub trait Resource: Clone + 'static {
|
||||
mut props: Vec<&str>,
|
||||
user: &User,
|
||||
rmap: &ResourceMap,
|
||||
) -> Result<
|
||||
ResponseElement<PropstatWrapper<EitherProp<Self::Prop, CommonPropertiesProp>>>,
|
||||
Self::Error,
|
||||
> {
|
||||
) -> Result<ResponseElement<EitherProp<Self::Prop, CommonPropertiesProp>>, Self::Error> {
|
||||
if props.contains(&"propname") {
|
||||
if props.len() != 1 {
|
||||
// propname MUST be the only queried prop per spec
|
||||
|
||||
@@ -4,8 +4,7 @@ use actix_web::{dev::ResourceMap, http::Method, web, HttpRequest, ResponseError}
|
||||
use async_trait::async_trait;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::methods::{route_delete, route_propfind, route_proppatch};
|
||||
|
||||
use super::methods::{route_delete, route_propfind, route_proppatch};
|
||||
use super::Resource;
|
||||
|
||||
#[async_trait(?Send)]
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
pub mod multistatus;
|
||||
mod propfind;
|
||||
mod resourcetype;
|
||||
pub mod tag_list;
|
||||
pub mod tag_name;
|
||||
|
||||
pub use propfind::{PropElement, PropfindType};
|
||||
|
||||
use derive_more::derive::From;
|
||||
pub use multistatus::MultistatusElement;
|
||||
pub use tag_list::TagList;
|
||||
|
||||
@@ -37,7 +37,7 @@ pub struct ResponseElement<PropstatType: Serialize> {
|
||||
pub href: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub status: Option<String>,
|
||||
pub propstat: Vec<PropstatType>,
|
||||
pub propstat: Vec<PropstatWrapper<PropstatType>>,
|
||||
}
|
||||
|
||||
impl<PT: Serialize> Default for ResponseElement<PT> {
|
||||
@@ -55,11 +55,11 @@ impl<PT: Serialize> Default for ResponseElement<PT> {
|
||||
// Extended by sync-token as specified in RFC 6578
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename = "multistatus", rename_all = "kebab-case")]
|
||||
pub struct MultistatusElement<T1: Serialize, T2: Serialize> {
|
||||
pub struct MultistatusElement<PropType: Serialize, MemberPropType: Serialize> {
|
||||
#[serde(rename = "response")]
|
||||
pub responses: Vec<ResponseElement<T1>>,
|
||||
pub responses: Vec<ResponseElement<PropType>>,
|
||||
#[serde(rename = "response")]
|
||||
pub member_responses: Vec<ResponseElement<T2>>,
|
||||
pub member_responses: Vec<ResponseElement<MemberPropType>>,
|
||||
#[serde(rename = "@xmlns")]
|
||||
pub ns_dav: &'static str,
|
||||
#[serde(rename = "@xmlns:C")]
|
||||
|
||||
17
crates/dav/src/xml/propfind.rs
Normal file
17
crates/dav/src/xml/propfind.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
use super::TagList;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct PropElement {
|
||||
#[serde(flatten)]
|
||||
pub prop: TagList,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum PropfindType {
|
||||
Propname,
|
||||
Allprop,
|
||||
Prop(PropElement),
|
||||
}
|
||||
Reference in New Issue
Block a user