mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-14 11:42:25 +00:00
birthday calendar, lots of refactoring
This commit is contained in:
@@ -61,11 +61,13 @@ pub(crate) async fn route_propfind<R: ResourceService>(
|
||||
|
||||
let mut member_responses = Vec::new();
|
||||
if depth != Depth::Zero {
|
||||
for (path, member) in resource_service
|
||||
.get_members(&path, req.resource_map())
|
||||
.await?
|
||||
{
|
||||
member_responses.push(member.propfind(&path, &props, &user, req.resource_map())?);
|
||||
for (subpath, member) in resource_service.get_members(&path).await? {
|
||||
member_responses.push(member.propfind(
|
||||
&format!("{}/{}", req.path().trim_end_matches('/'), subpath),
|
||||
&props,
|
||||
&user,
|
||||
req.resource_map(),
|
||||
)?);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ use crate::xml::{multistatus::ResponseElement, TagList};
|
||||
use crate::xml::{HrefElement, Resourcetype};
|
||||
use crate::Error;
|
||||
use actix_web::dev::ResourceMap;
|
||||
use actix_web::error::UrlGenerationError;
|
||||
use actix_web::test::TestRequest;
|
||||
use actix_web::{http::StatusCode, ResponseError};
|
||||
use itertools::Itertools;
|
||||
pub use resource_service::ResourceService;
|
||||
@@ -17,6 +15,8 @@ use strum::{EnumString, VariantNames};
|
||||
mod methods;
|
||||
mod resource_service;
|
||||
|
||||
pub use resource_service::*;
|
||||
|
||||
pub trait ResourceProp: XmlSerialize + XmlDeserialize {}
|
||||
impl<T: XmlSerialize + XmlDeserialize> ResourceProp for T {}
|
||||
|
||||
@@ -62,7 +62,7 @@ pub trait Resource: Clone + 'static {
|
||||
type PropName: ResourcePropName + From<Self::Prop> + Into<&'static str>;
|
||||
type Prop: ResourceProp + PartialEq + Clone;
|
||||
type Error: ResponseError + From<crate::Error>;
|
||||
type PrincipalResource: Resource;
|
||||
type PrincipalResource: Resource + NamedRoute;
|
||||
|
||||
fn get_resourcetype(&self) -> Resourcetype;
|
||||
|
||||
@@ -115,27 +115,10 @@ pub trait Resource: Clone + 'static {
|
||||
Err(crate::Error::PropReadOnly)
|
||||
}
|
||||
|
||||
fn resource_name() -> &'static str;
|
||||
|
||||
fn get_owner(&self) -> Option<&str> {
|
||||
None
|
||||
}
|
||||
|
||||
fn get_url<U, I>(rmap: &ResourceMap, elements: U) -> Result<String, UrlGenerationError>
|
||||
where
|
||||
U: IntoIterator<Item = I>,
|
||||
I: AsRef<str>,
|
||||
{
|
||||
Ok(rmap
|
||||
.url_for(
|
||||
&TestRequest::default().to_http_request(),
|
||||
Self::resource_name(),
|
||||
elements,
|
||||
)?
|
||||
.path()
|
||||
.to_owned())
|
||||
}
|
||||
|
||||
fn get_user_privileges(&self, user: &User) -> Result<UserPrivilegeSet, Self::Error>;
|
||||
|
||||
fn propfind(
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use actix_web::dev::{AppService, HttpServiceFactory};
|
||||
use actix_web::error::UrlGenerationError;
|
||||
use actix_web::test::TestRequest;
|
||||
use actix_web::web::Data;
|
||||
use actix_web::{dev::ResourceMap, http::Method, web, ResponseError};
|
||||
use async_trait::async_trait;
|
||||
use serde::Deserialize;
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::methods::{route_delete, route_propfind, route_proppatch};
|
||||
use super::Resource;
|
||||
@@ -17,8 +19,7 @@ pub trait ResourceService: Sized + 'static {
|
||||
|
||||
async fn get_members(
|
||||
&self,
|
||||
_path: &Self::PathComponents,
|
||||
_rmap: &ResourceMap,
|
||||
_path_components: &Self::PathComponents,
|
||||
) -> Result<Vec<(String, Self::MemberType)>, Self::Error> {
|
||||
Ok(vec![])
|
||||
}
|
||||
@@ -42,17 +43,11 @@ pub trait ResourceService: Sized + 'static {
|
||||
Err(crate::Error::Unauthorized.into())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn resource_name() -> &'static str {
|
||||
Self::Resource::resource_name()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn actix_resource(self) -> actix_web::Resource {
|
||||
Self::actix_additional_routes(
|
||||
web::resource("")
|
||||
.app_data(Data::new(self))
|
||||
.name(Self::resource_name())
|
||||
.route(
|
||||
web::method(Method::from_str("PROPFIND").unwrap()).to(route_propfind::<Self>),
|
||||
)
|
||||
@@ -69,3 +64,30 @@ pub trait ResourceService: Sized + 'static {
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
pub trait NamedRoute {
|
||||
fn route_name() -> &'static str;
|
||||
|
||||
fn get_url<U, I>(rmap: &ResourceMap, elements: U) -> Result<String, UrlGenerationError>
|
||||
where
|
||||
U: IntoIterator<Item = I>,
|
||||
I: AsRef<str>,
|
||||
{
|
||||
Ok(rmap
|
||||
.url_for(
|
||||
&TestRequest::default().to_http_request(),
|
||||
Self::route_name(),
|
||||
elements,
|
||||
)?
|
||||
.path()
|
||||
.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ResourceServiceRoute<RS: ResourceService>(pub RS);
|
||||
|
||||
impl<RS: ResourceService> HttpServiceFactory for ResourceServiceRoute<RS> {
|
||||
fn register(self, config: &mut AppService) {
|
||||
self.0.actix_resource().register(config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
use crate::privileges::UserPrivilegeSet;
|
||||
use crate::resource::{Resource, ResourceService};
|
||||
use crate::resource::{NamedRoute, Resource, ResourceService};
|
||||
use crate::xml::{Resourcetype, ResourcetypeInner};
|
||||
use actix_web::dev::ResourceMap;
|
||||
use async_trait::async_trait;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_xml::{XmlDeserialize, XmlSerialize};
|
||||
use serde::Serialize;
|
||||
use std::any::type_name;
|
||||
use std::marker::PhantomData;
|
||||
use strum::{EnumString, IntoStaticStr, VariantNames};
|
||||
|
||||
@@ -32,7 +31,7 @@ impl From<RootResourceProp> for RootResourcePropName {
|
||||
}
|
||||
}
|
||||
|
||||
impl<PR: Resource> Resource for RootResource<PR> {
|
||||
impl<PR: Resource + NamedRoute> Resource for RootResource<PR> {
|
||||
type PropName = RootResourcePropName;
|
||||
type Prop = RootResourceProp;
|
||||
type Error = PR::Error;
|
||||
@@ -51,16 +50,12 @@ impl<PR: Resource> Resource for RootResource<PR> {
|
||||
unreachable!("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(Clone)]
|
||||
pub struct RootResourceService<PR: Resource>(PhantomData<PR>);
|
||||
|
||||
impl<PR: Resource> Default for RootResourceService<PR> {
|
||||
@@ -70,7 +65,7 @@ impl<PR: Resource> Default for RootResourceService<PR> {
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl<PR: Resource> ResourceService for RootResourceService<PR> {
|
||||
impl<PR: Resource + NamedRoute> ResourceService for RootResourceService<PR> {
|
||||
type PathComponents = ();
|
||||
type MemberType = PR;
|
||||
type Resource = RootResource<PR>;
|
||||
|
||||
Reference in New Issue
Block a user