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}