dav_server/
ls.rs

1//! Contains the structs and traits that define a `locksystem` backend.
2//!
3//! Note that the methods DO NOT return futures, they are synchronous.
4//! This is because currently only two locksystems exist, `MemLs` and `FakeLs`.
5//! Both of them do not do any I/O, all methods return instantly.
6//!
7//! If ever a locksystem gets built that does I/O (to a filesystem,
8//! a database, or over the network) we'll need to revisit this.
9//!
10use crate::davpath::DavPath;
11use std::fmt::Debug;
12use std::pin::Pin;
13use std::time::{Duration, SystemTime};
14
15use dyn_clone::{clone_trait_object, DynClone};
16use futures_util::Future;
17use xmltree::Element;
18
19/// Type of the locks returned by DavLockSystem methods.
20#[derive(Debug, Clone)]
21pub struct DavLock {
22    /// Token.
23    pub token: String,
24    /// Path/
25    pub path: DavPath,
26    /// Principal.
27    pub principal: Option<String>,
28    /// Owner.
29    pub owner: Option<Element>,
30    /// When the lock turns stale (absolute).
31    pub timeout_at: Option<SystemTime>,
32    /// When the lock turns stale (relative).
33    pub timeout: Option<Duration>,
34    /// Shared.
35    pub shared: bool,
36    /// Deep.
37    pub deep: bool,
38}
39
40pub type LsFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
41
42/// The trait that defines a locksystem.
43pub trait DavLockSystem: Debug + Send + Sync + DynClone {
44    /// Lock a node. Returns `Ok(new_lock)` if succeeded,
45    /// or `Err(conflicting_lock)` if failed.
46    fn lock(
47        &self,
48        path: &DavPath,
49        principal: Option<&str>,
50        owner: Option<&Element>,
51        timeout: Option<Duration>,
52        shared: bool,
53        deep: bool,
54    ) -> LsFuture<Result<DavLock, DavLock>>;
55
56    /// Unlock a node. Returns `Ok(())` if succeeded, `Err (())` if failed
57    /// (because lock doesn't exist)
58    fn unlock(&self, path: &DavPath, token: &str) -> LsFuture<Result<(), ()>>;
59
60    /// Refresh lock. Returns updated lock if succeeded.
61    fn refresh(
62        &self,
63        path: &DavPath,
64        token: &str,
65        timeout: Option<Duration>,
66    ) -> LsFuture<Result<DavLock, ()>>;
67
68    /// Check if node is locked and if so, if we own all the locks.
69    /// If not, returns as Err one conflicting lock.
70    fn check(
71        &self,
72        path: &DavPath,
73        principal: Option<&str>,
74        ignore_principal: bool,
75        deep: bool,
76        submitted_tokens: Vec<&str>,
77    ) -> LsFuture<Result<(), DavLock>>;
78
79    /// Find and return all locks that cover a given path.
80    fn discover(&self, path: &DavPath) -> LsFuture<Vec<DavLock>>;
81
82    /// Delete all locks at this path and below (after MOVE or DELETE)
83    fn delete(&self, path: &DavPath) -> LsFuture<Result<(), ()>>;
84}
85
86clone_trait_object! {DavLockSystem}