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