webdav_handler/
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 sychronous.
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::time::{Duration, SystemTime};
13use xmltree::Element;
14
15/// Type of the locks returned by DavLockSystem methods.
16#[derive(Debug, Clone)]
17pub struct DavLock {
18    /// Token.
19    pub token:      String,
20    /// Path/
21    pub path:       DavPath,
22    /// Principal.
23    pub principal:  Option<String>,
24    /// Owner.
25    pub owner:      Option<Element>,
26    /// When the lock turns stale (absolute).
27    pub timeout_at: Option<SystemTime>,
28    /// When the lock turns stale (relative).
29    pub timeout:    Option<Duration>,
30    /// Shared.
31    pub shared:     bool,
32    /// Deep.
33    pub deep:       bool,
34}
35
36/// The trait that defines a locksystem.
37pub trait DavLockSystem: Debug + Sync + Send + BoxCloneLs {
38    /// Lock a node. Returns `Ok(new_lock)` if succeeded,
39    /// or `Err(conflicting_lock)` if failed.
40    fn lock(
41        &self,
42        path: &DavPath,
43        principal: Option<&str>,
44        owner: Option<&Element>,
45        timeout: Option<Duration>,
46        shared: bool,
47        deep: bool,
48    ) -> Result<DavLock, DavLock>;
49
50    /// Unlock a node. Returns `Ok(())` if succeeded, `Err (())` if failed
51    /// (because lock doesn't exist)
52    fn unlock(&self, path: &DavPath, token: &str) -> Result<(), ()>;
53
54    /// Refresh lock. Returns updated lock if succeeded.
55    fn refresh(&self, path: &DavPath, token: &str, timeout: Option<Duration>) -> Result<DavLock, ()>;
56
57    /// Check if node is locked and if so, if we own all the locks.
58    /// If not, returns as Err one conflicting lock.
59    fn check(
60        &self,
61        path: &DavPath,
62        principal: Option<&str>,
63        ignore_principal: bool,
64        deep: bool,
65        submitted_tokens: Vec<&str>,
66    ) -> Result<(), DavLock>;
67
68    /// Find and return all locks that cover a given path.
69    fn discover(&self, path: &DavPath) -> Vec<DavLock>;
70
71    /// Delete all locks at this path and below (after MOVE or DELETE)
72    fn delete(&self, path: &DavPath) -> Result<(), ()>;
73}
74
75#[doc(hidden)]
76pub trait BoxCloneLs {
77    fn box_clone(&self) -> Box<dyn DavLockSystem>;
78}
79
80// generic Clone, calls implementation-specific box_clone().
81impl Clone for Box<dyn DavLockSystem> {
82    fn clone(&self) -> Box<dyn DavLockSystem> {
83        self.box_clone()
84    }
85}
86
87// implementation-specific clone.
88#[doc(hidden)]
89impl<LS: Clone + DavLockSystem + 'static> BoxCloneLs for LS {
90    fn box_clone(&self) -> Box<dyn DavLockSystem> {
91        Box::new((*self).clone())
92    }
93}