mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-14 07:02:24 +00:00
outsource root resource to dav crate
This commit is contained in:
@@ -6,6 +6,7 @@ pub mod methods;
|
||||
pub mod namespace;
|
||||
pub mod privileges;
|
||||
pub mod resource;
|
||||
pub mod resources;
|
||||
pub mod xml;
|
||||
|
||||
pub use error::Error;
|
||||
|
||||
@@ -26,7 +26,7 @@ impl<T: ResourceReadProp + for<'de> Deserialize<'de>> ResourceProp for T {}
|
||||
pub trait ResourcePropName: FromStr + VariantNames {}
|
||||
impl<T: FromStr + VariantNames> ResourcePropName for T {}
|
||||
|
||||
pub trait Resource: Clone {
|
||||
pub trait Resource: Clone + 'static {
|
||||
type PropName: ResourcePropName;
|
||||
type Prop: ResourceProp;
|
||||
type Error: ResponseError + From<crate::Error>;
|
||||
@@ -132,6 +132,14 @@ pub trait Resource: Clone {
|
||||
}
|
||||
}
|
||||
|
||||
let mut prop_responses = Vec::new();
|
||||
|
||||
for extension in Self::list_extensions() {
|
||||
let (ext_invalid_props, ext_responses) = extension.propfind(self, props, user, rmap)?;
|
||||
props = ext_invalid_props;
|
||||
prop_responses.extend(ext_responses);
|
||||
}
|
||||
|
||||
let (valid_props, invalid_props): (Vec<Option<Self::PropName>>, Vec<Option<&str>>) = props
|
||||
.into_iter()
|
||||
.map(|prop| {
|
||||
@@ -143,19 +151,14 @@ pub trait Resource: Clone {
|
||||
})
|
||||
.unzip();
|
||||
let valid_props: Vec<Self::PropName> = valid_props.into_iter().flatten().collect();
|
||||
let mut invalid_props: Vec<&str> = invalid_props.into_iter().flatten().collect();
|
||||
let invalid_props: Vec<&str> = invalid_props.into_iter().flatten().collect();
|
||||
|
||||
let mut prop_responses = valid_props
|
||||
.into_iter()
|
||||
.map(|prop| self.get_prop(rmap, user, &prop))
|
||||
.collect::<Result<Vec<Self::Prop>, Self::Error>>()?;
|
||||
|
||||
for extension in Self::list_extensions() {
|
||||
let (ext_invalid_props, ext_responses) =
|
||||
extension.propfind(self, invalid_props, user, rmap)?;
|
||||
invalid_props = ext_invalid_props;
|
||||
prop_responses.extend(ext_responses);
|
||||
}
|
||||
prop_responses.extend(
|
||||
valid_props
|
||||
.into_iter()
|
||||
.map(|prop| self.get_prop(rmap, user, &prop))
|
||||
.collect::<Result<Vec<Self::Prop>, Self::Error>>()?,
|
||||
);
|
||||
|
||||
let mut propstats = vec![PropstatWrapper::Normal(PropstatElement {
|
||||
status: format!("HTTP/1.1 {}", StatusCode::OK),
|
||||
|
||||
3
crates/dav/src/resources/mod.rs
Normal file
3
crates/dav/src/resources/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub mod root;
|
||||
|
||||
pub use root::{RootResource, RootResourceService};
|
||||
82
crates/dav/src/resources/root.rs
Normal file
82
crates/dav/src/resources/root.rs
Normal file
@@ -0,0 +1,82 @@
|
||||
use std::any::type_name;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::extension::BoxedExtension;
|
||||
use crate::extensions::{
|
||||
CommonPropertiesExtension, CommonPropertiesProp, CommonPropertiesPropName,
|
||||
};
|
||||
use crate::privileges::UserPrivilegeSet;
|
||||
use crate::resource::{Resource, ResourceService};
|
||||
use actix_web::dev::ResourceMap;
|
||||
use actix_web::HttpRequest;
|
||||
use async_trait::async_trait;
|
||||
use rustical_store::auth::User;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Deserialize, Serialize, Default, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct Resourcetype {
|
||||
collection: (),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RootResource<PR: Resource>(PhantomData<PR>);
|
||||
|
||||
impl<PR: Resource> Default for RootResource<PR> {
|
||||
fn default() -> Self {
|
||||
Self(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<PR: Resource> Resource for RootResource<PR> {
|
||||
type PropName = CommonPropertiesPropName;
|
||||
type Prop = CommonPropertiesProp<RootResource<PR>>;
|
||||
type Error = PR::Error;
|
||||
type ResourceType = Resourcetype;
|
||||
|
||||
fn list_extensions() -> Vec<BoxedExtension<Self>> {
|
||||
vec![BoxedExtension::from_ext(
|
||||
CommonPropertiesExtension::<PR>::default(),
|
||||
)]
|
||||
}
|
||||
|
||||
fn get_prop(
|
||||
&self,
|
||||
_rmap: &ResourceMap,
|
||||
_user: &User,
|
||||
_prop: &Self::PropName,
|
||||
) -> Result<Self::Prop, Self::Error> {
|
||||
panic!("we shouldn't end up here")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn resource_name() -> &'static str {
|
||||
type_name::<Self>()
|
||||
}
|
||||
|
||||
fn get_user_privileges(&self, _user: &User) -> Result<UserPrivilegeSet, Self::Error> {
|
||||
Ok(UserPrivilegeSet::all())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct RootResourceService<PR: Resource>(PhantomData<PR>);
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl<PR: Resource> ResourceService for RootResourceService<PR> {
|
||||
type PathComponents = ();
|
||||
type MemberType = PR;
|
||||
type Resource = RootResource<PR>;
|
||||
type Error = PR::Error;
|
||||
|
||||
async fn new(
|
||||
_req: &HttpRequest,
|
||||
_path_components: Self::PathComponents,
|
||||
) -> Result<Self, Self::Error> {
|
||||
Ok(Self(Default::default()))
|
||||
}
|
||||
|
||||
async fn get_resource(&self) -> Result<Self::Resource, Self::Error> {
|
||||
Ok(RootResource::<PR>::default())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user