diff --git a/Cargo.toml b/Cargo.toml index 0b7198e..aa31daf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ readme = "README.md" description = "Rust WebDAV server library. A fork of the webdav-handler crate." repository = "https://github.com/messense/dav-server-rs" authors = ["Miquel van Smoorenburg ", "messense "] -edition = "2018" +edition = "2024" license = "Apache-2.0" keywords = ["webdav"] categories = ["web-programming"] diff --git a/examples/actix.rs b/examples/actix.rs index ea23eed..be0ece7 100644 --- a/examples/actix.rs +++ b/examples/actix.rs @@ -1,8 +1,8 @@ use std::io; -use actix_web::{web, App, HttpServer}; +use actix_web::{App, HttpServer, web}; use dav_server::actix::*; -use dav_server::{fakels::FakeLs, localfs::LocalFs, DavConfig, DavHandler}; +use dav_server::{DavConfig, DavHandler, fakels::FakeLs, localfs::LocalFs}; pub async fn dav_handler(req: DavRequest, davhandler: web::Data) -> DavResponse { if let Some(prefix) = req.prefix() { diff --git a/examples/auth.rs b/examples/auth.rs index f6e85e1..84c321e 100644 --- a/examples/auth.rs +++ b/examples/auth.rs @@ -1,12 +1,13 @@ use std::{convert::Infallible, fmt::Display, net::SocketAddr, path::Path}; -use futures_util::{stream, StreamExt}; +use futures_util::{StreamExt, stream}; use http::{Request, Response, StatusCode}; use hyper::{body::Incoming, server::conn::http1, service::service_fn}; use hyper_util::rt::TokioIo; use tokio::{net::TcpListener, task::spawn}; use dav_server::{ + DavHandler, body::Body, davpath::DavPath, fakels::FakeLs, @@ -15,7 +16,6 @@ use dav_server::{ OpenOptions, ReadDirMeta, }, localfs::LocalFs, - DavHandler, }; /// The server example demonstrates a limited scope policy for access to the file system. @@ -129,7 +129,7 @@ enum Filter { impl Filter { fn from_request(request: &Request) -> Result> { - use headers::{authorization::Basic, Authorization, HeaderMapExt}; + use headers::{Authorization, HeaderMapExt, authorization::Basic}; let auth = request .headers() diff --git a/examples/hyper.rs b/examples/hyper.rs index 59cc181..871c277 100644 --- a/examples/hyper.rs +++ b/examples/hyper.rs @@ -4,7 +4,7 @@ use hyper::{server::conn::http1, service::service_fn}; use hyper_util::rt::TokioIo; use tokio::net::TcpListener; -use dav_server::{fakels::FakeLs, localfs::LocalFs, DavHandler}; +use dav_server::{DavHandler, fakels::FakeLs, localfs::LocalFs}; #[tokio::main] async fn main() { diff --git a/examples/sample-litmus-server.rs b/examples/sample-litmus-server.rs index ec28dac..8a3a89d 100644 --- a/examples/sample-litmus-server.rs +++ b/examples/sample-litmus-server.rs @@ -8,12 +8,12 @@ use std::{convert::Infallible, error::Error, net::SocketAddr}; use clap::Parser; -use headers::{authorization::Basic, Authorization, HeaderMapExt}; +use headers::{Authorization, HeaderMapExt, authorization::Basic}; use hyper::{server::conn::http1, service::service_fn}; use hyper_util::rt::TokioIo; use tokio::net::TcpListener; -use dav_server::{body::Body, fakels, localfs, memfs, memls, DavConfig, DavHandler}; +use dav_server::{DavConfig, DavHandler, body::Body, fakels, localfs, memfs, memls}; #[derive(Clone)] struct Server { diff --git a/src/actix.rs b/src/actix.rs index 4f4bfe2..55c283c 100644 --- a/src/actix.rs +++ b/src/actix.rs @@ -21,9 +21,9 @@ use std::{ use actix_web::body::BoxBody; use actix_web::error::PayloadError; -use actix_web::{dev, Error, FromRequest, HttpRequest, HttpResponse}; +use actix_web::{Error, FromRequest, HttpRequest, HttpResponse, dev}; use bytes::Bytes; -use futures_util::{future, Stream}; +use futures_util::{Stream, future}; use pin_project::pin_project; /// http::Request compatibility. diff --git a/src/conditional.rs b/src/conditional.rs index bb68c40..e5681b0 100644 --- a/src/conditional.rs +++ b/src/conditional.rs @@ -58,7 +58,7 @@ pub(crate) fn http_if_match(req: &Request, meta: Option<&dyn DavMetaData>) -> Op if let Some(r) = req.headers().typed_get::() { let etag = meta.and_then(ETag::from_meta); if !etaglist_match(&r.0, meta.is_some(), etag.as_ref()) { - trace!("precondition fail: If-Match {:?}", r); + trace!("precondition fail: If-Match {r:?}"); return Some(StatusCode::PRECONDITION_FAILED); } } else if let Some(r) = req.headers().typed_get::() { @@ -66,7 +66,7 @@ pub(crate) fn http_if_match(req: &Request, meta: Option<&dyn DavMetaData>) -> Op None => return Some(StatusCode::PRECONDITION_FAILED), Some(file_modified) => { if round_time(file_modified) > round_time(r) { - trace!("precondition fail: If-Unmodified-Since {:?}", r); + trace!("precondition fail: If-Unmodified-Since {r:?}"); return Some(StatusCode::PRECONDITION_FAILED); } } @@ -76,22 +76,20 @@ pub(crate) fn http_if_match(req: &Request, meta: Option<&dyn DavMetaData>) -> Op if let Some(r) = req.headers().typed_get::() { let etag = meta.and_then(ETag::from_meta); if etaglist_match(&r.0, meta.is_some(), etag.as_ref()) { - trace!("precondition fail: If-None-Match {:?}", r); + trace!("precondition fail: If-None-Match {r:?}"); if req.method() == Method::GET || req.method() == Method::HEAD { return Some(StatusCode::NOT_MODIFIED); } else { return Some(StatusCode::PRECONDITION_FAILED); } } - } else if let Some(r) = req.headers().typed_get::() { - if req.method() == Method::GET || req.method() == Method::HEAD { - if let Some(file_modified) = file_modified { - if round_time(file_modified) <= round_time(r) { - trace!("not-modified If-Modified-Since {:?}", r); - return Some(StatusCode::NOT_MODIFIED); - } - } - } + } else if let Some(r) = req.headers().typed_get::() + && (req.method() == Method::GET || req.method() == Method::HEAD) + && let Some(file_modified) = file_modified + && round_time(file_modified) <= round_time(r) + { + trace!("not-modified If-Modified-Since {r:?}"); + return Some(StatusCode::NOT_MODIFIED); } None } diff --git a/src/davhandler.rs b/src/davhandler.rs index 02fa848..1b7bfd6 100644 --- a/src/davhandler.rs +++ b/src/davhandler.rs @@ -17,13 +17,13 @@ use http_body_util::BodyExt; use crate::body::{Body, StreamBody}; use crate::davheaders; use crate::davpath::DavPath; -use crate::util::{dav_method, DavMethod, DavMethodSet}; +use crate::util::{DavMethod, DavMethodSet, dav_method}; +use crate::DavResult; use crate::errors::DavError; use crate::fs::*; use crate::ls::*; -use crate::voidfs::{is_voidfs, VoidFs}; -use crate::DavResult; +use crate::voidfs::{VoidFs, is_voidfs}; /// WebDAV request handler. /// @@ -416,7 +416,7 @@ where resp } Err(err) => { - debug!("== END REQUEST result {:?}", err); + debug!("== END REQUEST result {err:?}"); let mut resp = Response::builder(); if is_ms && err.statuscode() == StatusCode::NOT_FOUND { // This is an attempt to convince Windows to not @@ -459,10 +459,10 @@ where }; // debug when running the webdav litmus tests. - if log_enabled!(log::Level::Debug) { - if let Some(t) = req.headers().typed_get::() { - debug!("X-Litmus: {:?}", t); - } + if log_enabled!(log::Level::Debug) + && let Some(t) = req.headers().typed_get::() + { + debug!("X-Litmus: {t:?}"); } // translate HTTP method to Webdav method. @@ -497,15 +497,15 @@ where } // see if method is allowed. - if let Some(ref a) = self.allow { - if !a.contains(method) { - debug!( - "method {} not allowed on request {}", - req.method(), - req.uri() - ); - return Err(DavError::StatusClose(StatusCode::METHOD_NOT_ALLOWED)); - } + if let Some(ref a) = self.allow + && !a.contains(method) + { + debug!( + "method {} not allowed on request {}", + req.method(), + req.uri() + ); + return Err(DavError::StatusClose(StatusCode::METHOD_NOT_ALLOWED)); } // make sure the request path is valid. @@ -532,7 +532,7 @@ where } } - debug!("== START REQUEST {:?} {}", method, path); + debug!("== START REQUEST {method:?} {path}"); match method { DavMethod::Options => self.handle_options(&req).await, diff --git a/src/davheaders.rs b/src/davheaders.rs index 04a6b5b..a1779e6 100644 --- a/src/davheaders.rs +++ b/src/davheaders.rs @@ -48,7 +48,7 @@ fn map_invalid(_e: impl std::error::Error) -> headers::Error { } macro_rules! header { - ($tname:ident, $hname:ident, $sname:expr) => { + ($tname:ident, $hname:ident, $sname:expr_2021) => { lazy_static! { pub static ref $hname: HeaderName = HeaderName::from_static($sname); } @@ -226,7 +226,7 @@ impl Header for Timeout { } first = false; match *s { - DavTimeout::Seconds(n) => value.push_str(&format!("Second-{}", n)), + DavTimeout::Seconds(n) => value.push_str(&format!("Second-{n}")), DavTimeout::Infinite => value.push_str("Infinite"), } } @@ -250,10 +250,10 @@ impl Header for Destination { if s.starts_with('/') { return Ok(Destination(s.to_string())); } - if let Some(caps) = RE_URL.captures(s) { - if let Some(path) = caps.get(1) { - return Ok(Destination(path.as_str().to_string())); - } + if let Some(caps) = RE_URL.captures(s) + && let Some(path) = caps.get(1) + { + return Ok(Destination(path.as_str().to_string())); } Err(invalid()) } @@ -313,7 +313,7 @@ impl ETag { } else { let w = if weak { "W/" } else { "" }; Ok(ETag { - tag: format!("{}\"{}\"", w, t), + tag: format!("{w}\"{t}\""), weak, }) } @@ -322,7 +322,7 @@ impl ETag { pub fn from_meta(meta: &dyn DavMetaData) -> Option { let tag = meta.etag()?; Some(ETag { - tag: format!("\"{}\"", tag), + tag: format!("\"{tag}\""), weak: false, }) } @@ -587,9 +587,9 @@ impl Header for XUpdateRange { { let value = match *self { XUpdateRange::Append => "append".to_string(), - XUpdateRange::FromTo(b, e) => format!("{}-{}", b, e), - XUpdateRange::AllFrom(b) => format!("{}-", b), - XUpdateRange::Last(e) => format!("-{}", e), + XUpdateRange::FromTo(b, e) => format!("{b}-{e}"), + XUpdateRange::AllFrom(b) => format!("{b}-"), + XUpdateRange::Last(e) => format!("-{e}"), }; values.extend(std::iter::once(HeaderValue::from_str(&value).unwrap())); } @@ -654,10 +654,10 @@ enum IfState { // helpers. fn is_whitespace(c: u8) -> bool { - b" \t\r\n".iter().any(|&x| x == c) + b" \t\r\n".contains(&c) } fn is_special(c: u8) -> bool { - b"<>()[]".iter().any(|&x| x == c) + b"<>()[]".contains(&c) } fn trim_left(mut out: &'_ [u8]) -> &'_ [u8] { diff --git a/src/davpath.rs b/src/davpath.rs index acfecbb..d628327 100644 --- a/src/davpath.rs +++ b/src/davpath.rs @@ -69,7 +69,7 @@ impl Error for ParseError { impl std::fmt::Display for ParseError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{:?}", self) + write!(f, "{self:?}") } } @@ -422,12 +422,11 @@ impl DavPathRef { pub(crate) fn get_mime_type_str(&self) -> &'static str { let name = self.file_name_bytes(); let d = name.rsplitn(2, |&c| c == b'.').collect::>(); - if d.len() > 1 { - if let Ok(ext) = std::str::from_utf8(d[0]) { - if let Some(t) = mime_guess::from_ext(ext).first_raw() { - return t; - } - } + if d.len() > 1 + && let Ok(ext) = std::str::from_utf8(d[0]) + && let Some(t) = mime_guess::from_ext(ext).first_raw() + { + return t; } "application/octet-stream" } diff --git a/src/errors.rs b/src/errors.rs index 6d692d0..95c1ab7 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -47,7 +47,7 @@ impl std::fmt::Display for DavError { DavError::XmlReaderError(_) => write!(f, "XML parse error"), DavError::XmlWriterError(_) => write!(f, "XML generate error"), DavError::IoError(_) => write!(f, "I/O error"), - _ => write!(f, "{:?}", self), + _ => write!(f, "{self:?}"), } } } @@ -63,7 +63,7 @@ impl From for io::Error { match e { DavError::IoError(e) => e, DavError::FsError(e) => e.into(), - _ => io::Error::new(io::ErrorKind::Other, e), + _ => io::Error::other(e), } } } @@ -118,16 +118,16 @@ impl From for DavError { fn fserror_to_ioerror(e: FsError) -> io::Error { match e { - FsError::NotImplemented => io::Error::new(io::ErrorKind::Other, "NotImplemented"), - FsError::GeneralFailure => io::Error::new(io::ErrorKind::Other, "GeneralFailure"), + FsError::NotImplemented => io::Error::other("NotImplemented"), + FsError::GeneralFailure => io::Error::other("GeneralFailure"), FsError::Exists => io::Error::new(io::ErrorKind::AlreadyExists, "Exists"), FsError::NotFound => io::Error::new(io::ErrorKind::NotFound, "Notfound"), FsError::Forbidden => io::Error::new(io::ErrorKind::PermissionDenied, "Forbidden"), - FsError::InsufficientStorage => io::Error::new(io::ErrorKind::Other, "InsufficientStorage"), - FsError::LoopDetected => io::Error::new(io::ErrorKind::Other, "LoopDetected"), - FsError::PathTooLong => io::Error::new(io::ErrorKind::Other, "PathTooLong"), - FsError::TooLarge => io::Error::new(io::ErrorKind::Other, "TooLarge"), - FsError::IsRemote => io::Error::new(io::ErrorKind::Other, "IsRemote"), + FsError::InsufficientStorage => io::Error::other("InsufficientStorage"), + FsError::LoopDetected => io::Error::other("LoopDetected"), + FsError::PathTooLong => io::Error::other("PathTooLong"), + FsError::TooLarge => io::Error::other("TooLarge"), + FsError::IsRemote => io::Error::other("IsRemote"), } } diff --git a/src/fakels.rs b/src/fakels.rs index d392193..2378307 100644 --- a/src/fakels.rs +++ b/src/fakels.rs @@ -14,7 +14,7 @@ //! `FakeLs` implements such a fake locksystem. use std::time::{Duration, SystemTime}; -use futures_util::{future, FutureExt}; +use futures_util::{FutureExt, future}; use uuid::Uuid; use xmltree::Element; @@ -47,14 +47,14 @@ fn tm_limit(d: Option) -> Duration { impl DavLockSystem for FakeLs { fn lock( - &self, + &'_ self, path: &DavPath, principal: Option<&str>, owner: Option<&Element>, timeout: Option, shared: bool, deep: bool, - ) -> LsFuture> { + ) -> LsFuture<'_, Result> { let timeout = tm_limit(timeout); let timeout_at = SystemTime::now() + timeout; @@ -64,9 +64,9 @@ impl DavLockSystem for FakeLs { let lock = DavLock { token, - path: path.clone(), + path: Box::new(path.clone()), principal: principal.map(|s| s.to_string()), - owner: owner.cloned(), + owner: owner.map(|o| Box::new(o.clone())), timeout_at: Some(timeout_at), timeout: Some(timeout), shared, @@ -76,17 +76,17 @@ impl DavLockSystem for FakeLs { future::ready(Ok(lock)).boxed() } - fn unlock(&self, _path: &DavPath, _token: &str) -> LsFuture> { + fn unlock(&'_ self, _path: &DavPath, _token: &str) -> LsFuture<'_, Result<(), ()>> { future::ready(Ok(())).boxed() } fn refresh( - &self, + &'_ self, path: &DavPath, token: &str, timeout: Option, - ) -> LsFuture> { - debug!("refresh lock {}", token); + ) -> LsFuture<'_, Result> { + debug!("refresh lock {token}"); let v: Vec<&str> = token.split('/').collect(); let deep = v.len() > 1 && v[1] == "I"; let shared = v.len() > 2 && v[2] == "S"; @@ -96,7 +96,7 @@ impl DavLockSystem for FakeLs { let lock = DavLock { token: token.to_string(), - path: path.clone(), + path: Box::new(path.clone()), principal: None, owner: None, timeout_at: Some(timeout_at), @@ -108,21 +108,21 @@ impl DavLockSystem for FakeLs { } fn check( - &self, + &'_ self, _path: &DavPath, _principal: Option<&str>, _ignore_principal: bool, _deep: bool, _submitted_tokens: Vec<&str>, - ) -> LsFuture> { + ) -> LsFuture<'_, Result<(), DavLock>> { future::ready(Ok(())).boxed() } - fn discover(&self, _path: &DavPath) -> LsFuture> { + fn discover(&'_ self, _path: &DavPath) -> LsFuture<'_, Vec> { future::ready(Vec::new()).boxed() } - fn delete(&self, _path: &DavPath) -> LsFuture> { + fn delete(&'_ self, _path: &DavPath) -> LsFuture<'_, Result<(), ()>> { future::ready(Ok(())).boxed() } } diff --git a/src/fs.rs b/src/fs.rs index 4b8ee1f..ee03682 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -8,20 +8,20 @@ use std::io::SeekFrom; use std::pin::Pin; use std::time::{SystemTime, UNIX_EPOCH}; -use dyn_clone::{clone_trait_object, DynClone}; -use futures_util::{future, Future, FutureExt, Stream, TryFutureExt}; +use dyn_clone::{DynClone, clone_trait_object}; +use futures_util::{Future, FutureExt, Stream, TryFutureExt, future}; use http::StatusCode; use crate::davpath::DavPath; macro_rules! notimplemented { - ($method:expr) => { + ($method:expr_2021) => { Err(FsError::NotImplemented) }; } macro_rules! notimplemented_fut { - ($method:expr) => { + ($method:expr_2021) => { Box::pin(future::ready(Err(FsError::NotImplemented))) }; } @@ -280,7 +280,7 @@ pub trait DavFileSystem { /// /// The default implementation returns [`FsError::NotImplemented`]. #[allow(unused_variables)] - fn get_quota(&self) -> FsFuture<(u64, Option)> { + fn get_quota(&'_ self) -> FsFuture<'_, (u64, Option)> { notimplemented_fut!("get_quota") } } @@ -629,7 +629,7 @@ impl GuardedFileSystem<()> for Fs { DavFileSystem::get_prop(self, path, prop) } - fn get_quota(&self, _credentials: &()) -> FsFuture<(u64, Option)> { + fn get_quota(&'_ self, _credentials: &()) -> FsFuture<'_, (u64, Option)> { DavFileSystem::get_quota(self) } } @@ -640,23 +640,23 @@ pub trait DavDirEntry: Send + Sync { fn name(&self) -> Vec; /// Metadata of the entry. - fn metadata(&self) -> FsFuture>; + fn metadata(&'_ self) -> FsFuture<'_, Box>; /// Default implementation of `is_dir` just returns `metadata()?.is_dir()`. /// Implementations can override this if their `metadata()` method is /// expensive and there is a cheaper way to provide the same info /// (e.g. dirent.d_type in unix filesystems). - fn is_dir(&self) -> FsFuture { + fn is_dir(&'_ self) -> FsFuture<'_, bool> { Box::pin(self.metadata().and_then(|meta| future::ok(meta.is_dir()))) } /// Likewise. Default: `!is_dir()`. - fn is_file(&self) -> FsFuture { + fn is_file(&'_ self) -> FsFuture<'_, bool> { Box::pin(self.metadata().and_then(|meta| future::ok(meta.is_file()))) } /// Likewise. Default: `false`. - fn is_symlink(&self) -> FsFuture { + fn is_symlink(&'_ self) -> FsFuture<'_, bool> { Box::pin( self.metadata() .and_then(|meta| future::ok(meta.is_symlink())), @@ -667,13 +667,13 @@ pub trait DavDirEntry: Send + Sync { /// A `DavFile` is the equivalent of `std::fs::File`, should be /// readable/writeable/seekable, and be able to return its metadata. pub trait DavFile: Debug + Send + Sync { - fn metadata(&mut self) -> FsFuture>; - fn write_buf(&mut self, buf: Box) -> FsFuture<()>; - fn write_bytes(&mut self, buf: bytes::Bytes) -> FsFuture<()>; - fn read_bytes(&mut self, count: usize) -> FsFuture; - fn seek(&mut self, pos: SeekFrom) -> FsFuture; - fn flush(&mut self) -> FsFuture<()>; - fn redirect_url(&mut self) -> FsFuture> { + fn metadata(&'_ mut self) -> FsFuture<'_, Box>; + fn write_buf(&'_ mut self, buf: Box) -> FsFuture<'_, ()>; + fn write_bytes(&'_ mut self, buf: bytes::Bytes) -> FsFuture<'_, ()>; + fn read_bytes(&'_ mut self, count: usize) -> FsFuture<'_, bytes::Bytes>; + fn seek(&'_ mut self, pos: SeekFrom) -> FsFuture<'_, u64>; + fn flush(&'_ mut self) -> FsFuture<'_, ()>; + fn redirect_url(&'_ mut self) -> FsFuture<'_, Option> { future::ready(Ok(None)).boxed() } } @@ -692,16 +692,16 @@ pub trait DavMetaData: Debug + Send + Sync + DynClone { /// Returns a simple etag that basically is `\-\` /// with the numbers in hex. Enough for most implementations. fn etag(&self) -> Option { - if let Ok(t) = self.modified() { - if let Ok(t) = t.duration_since(UNIX_EPOCH) { - let t = t.as_secs() * 1000000 + t.subsec_nanos() as u64 / 1000; - let tag = if self.is_file() && self.len() > 0 { - format!("{:x}-{:x}", self.len(), t) - } else { - format!("{:x}", t) - }; - return Some(tag); - } + if let Ok(t) = self.modified() + && let Ok(t) = t.duration_since(UNIX_EPOCH) + { + let t = t.as_secs() * 1000000 + t.subsec_nanos() as u64 / 1000; + let tag = if self.is_file() && self.len() > 0 { + format!("{:x}-{:x}", self.len(), t) + } else { + format!("{t:x}") + }; + return Some(tag); } None } @@ -818,6 +818,6 @@ impl std::error::Error for FsError { impl std::fmt::Display for FsError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{:?}", self) + write!(f, "{self:?}") } } diff --git a/src/handle_copymove.rs b/src/handle_copymove.rs index efad825..f0935a7 100644 --- a/src/handle_copymove.rs +++ b/src/handle_copymove.rs @@ -1,4 +1,4 @@ -use futures_util::{future::BoxFuture, FutureExt, StreamExt}; +use futures_util::{FutureExt, StreamExt, future::BoxFuture}; use headers::HeaderMapExt; use http::{Request, Response, StatusCode}; @@ -9,8 +9,8 @@ use crate::davheaders::{self, Depth}; use crate::davpath::DavPath; use crate::errors::*; use crate::fs::*; -use crate::multierror::{multi_error, MultiError}; -use crate::{util::DavMethod, DavInner, DavResult}; +use crate::multierror::{MultiError, multi_error}; +use crate::{DavInner, DavResult, util::DavMethod}; // map_err helper. async fn add_status<'a>( @@ -52,7 +52,7 @@ impl DavInner { return match self.fs.copy(source, dest, &self.credentials).await { Ok(_) => Ok(()), Err(e) => { - debug!("do_copy: self.fs.copy error: {:?}", e); + debug!("do_copy: self.fs.copy error: {e:?}"); add_status(multierror, source, e).await } }; @@ -61,11 +61,11 @@ impl DavInner { // Copying a directory onto an existing directory with Depth 0 // is not an error. It means "only copy properties" (which // we do not do yet). - if let Err(e) = self.fs.create_dir(dest, &self.credentials).await { - if depth != Depth::Zero || e != FsError::Exists { - debug!("do_copy: self.fs.create_dir({}) error: {:?}", dest, e); - return add_status(multierror, dest, e).await; - } + if let Err(e) = self.fs.create_dir(dest, &self.credentials).await + && (depth != Depth::Zero || e != FsError::Exists) + { + debug!("do_copy: self.fs.create_dir({dest}) error: {e:?}"); + return add_status(multierror, dest, e).await; } // only recurse when Depth > 0. @@ -80,7 +80,7 @@ impl DavInner { { Ok(entries) => entries, Err(e) => { - debug!("do_copy: self.fs.read_dir error: {:?}", e); + debug!("do_copy: self.fs.read_dir error: {e:?}"); return add_status(multierror, source, e).await; } }; @@ -196,10 +196,10 @@ impl DavInner { let (dest_is_file, dmeta) = match self.fs.symlink_metadata(&dest, &self.credentials).await { Ok(meta) => { let mut is_file = false; - if meta.is_symlink() { - if let Ok(m) = self.fs.metadata(&dest, &self.credentials).await { - is_file = m.is_file(); - } + if meta.is_symlink() + && let Ok(m) = self.fs.metadata(&dest, &self.credentials).await + { + is_file = m.is_file(); } if meta.is_file() { is_file = true; @@ -264,7 +264,7 @@ impl DavInner { // see if we need to delete the destination first. if overwrite && exists && depth != Depth::Zero && !dest_is_file { - trace!("handle_copymove: deleting destination {}", dest); + trace!("handle_copymove: deleting destination {dest}"); if self .delete_items(&mut multierror, Depth::Infinity, dmeta.unwrap(), &dest) .await diff --git a/src/handle_delete.rs b/src/handle_delete.rs index 493c537..ea4e280 100644 --- a/src/handle_delete.rs +++ b/src/handle_delete.rs @@ -1,4 +1,4 @@ -use futures_util::{future::BoxFuture, FutureExt, StreamExt}; +use futures_util::{FutureExt, StreamExt, future::BoxFuture}; use headers::HeaderMapExt; use http::{Request, Response, StatusCode}; @@ -9,7 +9,7 @@ use crate::davheaders::Depth; use crate::davpath::DavPath; use crate::errors::*; use crate::fs::*; -use crate::multierror::{multi_error, MultiError}; +use crate::multierror::{MultiError, multi_error}; use crate::{DavInner, DavResult}; // map_err helper. @@ -44,14 +44,14 @@ impl DavInner { ) -> BoxFuture<'a, DavResult<()>> { async move { if !meta.is_dir() { - trace!("delete_items (file) {} {:?}", path, depth); + trace!("delete_items (file) {path} {depth:?}"); return match self.fs.remove_file(path, &self.credentials).await { Ok(x) => Ok(x), Err(e) => Err(add_status(res, path, e).await), }; } if depth == Depth::Zero { - trace!("delete_items (dir) {} {:?}", path, depth); + trace!("delete_items (dir) {path} {depth:?}"); return match self.fs.remove_dir(path, &self.credentials).await { Ok(x) => Ok(x), Err(e) => Err(add_status(res, path, e).await), @@ -128,10 +128,10 @@ impl DavInner { let mut path = self.path(req); let meta = self.fs.symlink_metadata(&path, &self.credentials).await?; - if meta.is_symlink() { - if let Ok(m2) = self.fs.metadata(&path, &self.credentials).await { - path.add_slash_if(m2.is_dir()); - } + if meta.is_symlink() + && let Ok(m2) = self.fs.metadata(&path, &self.credentials).await + { + path.add_slash_if(m2.is_dir()); } path.add_slash_if(meta.is_dir()); diff --git a/src/handle_gethead.rs b/src/handle_gethead.rs index fa20e20..67f3812 100644 --- a/src/handle_gethead.rs +++ b/src/handle_gethead.rs @@ -3,7 +3,7 @@ use std::io::Write; use futures_util::StreamExt; use headers::HeaderMapExt; -use http::{status::StatusCode, Request, Response}; +use http::{Request, Response, status::StatusCode}; use bytes::Bytes; @@ -96,14 +96,13 @@ impl DavInner { res.headers_mut().typed_insert(etag); } - if let Some(redirect) = self.redirect { - if redirect { - if let Some(url) = file.redirect_url().await? { - res.headers_mut().insert("Location", url.parse().unwrap()); - *res.status_mut() = StatusCode::FOUND; - return Ok(res); - } - } + if let Some(redirect) = self.redirect + && redirect + && let Some(url) = file.redirect_url().await? + { + res.headers_mut().insert("Location", url.parse().unwrap()); + *res.status_mut() = StatusCode::FOUND; + return Ok(res); } // Apache always adds an Accept-Ranges header, even with partial @@ -129,31 +128,29 @@ impl DavInner { } // see if we want to get one or more ranges. - if do_range { - if let Some(r) = req.headers().typed_get::() { - trace!("handle_gethead: range header {:?}", r); - use std::ops::Bound::*; - for range in r.satisfiable_ranges(len) { - let (start, mut count, valid) = match range { - (Included(s), Included(e)) if e >= s => (s, e - s + 1, true), - (Included(s), Unbounded) if s <= len => (s, len - s, true), - (Unbounded, Included(n)) if n <= len => (len - n, n, true), - _ => (0, 0, false), - }; - if !valid || start >= len { - let r = format!("bytes */{}", len); - res.headers_mut() - .insert("Content-Range", r.parse().unwrap()); - *res.status_mut() = StatusCode::RANGE_NOT_SATISFIABLE; - ranges.clear(); - no_body = true; - break; - } - if start + count > len { - count = len - start; - } - ranges.push(Range { start, count }); + if do_range && let Some(r) = req.headers().typed_get::() { + trace!("handle_gethead: range header {r:?}"); + use std::ops::Bound::*; + for range in r.satisfiable_ranges(len) { + let (start, mut count, valid) = match range { + (Included(s), Included(e)) if e >= s => (s, e - s + 1, true), + (Included(s), Unbounded) if s <= len => (s, len - s, true), + (Unbounded, Included(n)) if n <= len => (len - n, n, true), + _ => (0, 0, false), + }; + if !valid || start >= len { + let r = format!("bytes */{len}"); + res.headers_mut() + .insert("Content-Range", r.parse().unwrap()); + *res.status_mut() = StatusCode::RANGE_NOT_SATISFIABLE; + ranges.clear(); + no_body = true; + break; } + if start + count > len { + count = len - start; + } + ranges.push(Range { start, count }); } } @@ -164,7 +161,7 @@ impl DavInner { .await .is_err() { - let r = format!("bytes */{}", len); + let r = format!("bytes */{len}"); res.headers_mut() .insert("Content-Range", r.parse().unwrap()); *res.status_mut() = StatusCode::RANGE_NOT_SATISFIABLE; @@ -189,7 +186,7 @@ impl DavInner { .insert("Content-Range", r.parse().unwrap()); } else { // add content-type header. - let r = format!("multipart/byteranges; boundary={}", BOUNDARY); + let r = format!("multipart/byteranges; boundary={BOUNDARY}"); res.headers_mut().insert("Content-Type", r.parse().unwrap()); } } else { @@ -228,8 +225,7 @@ impl DavInner { for range in ranges { trace!( "handle_get: start = {}, count = {}", - range.start, - range.count + range.start, range.count ); if curpos != range.start { // this should never fail, but if it does, just skip this range @@ -243,7 +239,7 @@ impl DavInner { if multipart { let mut hdrs = Vec::new(); - let _ = write!(hdrs, "{}", BOUNDARY_START); + let _ = write!(hdrs, "{BOUNDARY_START}"); let _ = writeln!( hdrs, "Content-Range: bytes {}-{}/{}", @@ -251,7 +247,7 @@ impl DavInner { range.start + range.count - 1, len ); - let _ = writeln!(hdrs, "Content-Type: {}", content_type); + let _ = writeln!(hdrs, "Content-Type: {content_type}"); let _ = writeln!(hdrs); tx.send(Bytes::from(hdrs)).await; } @@ -269,7 +265,7 @@ impl DavInner { let len = buf.len() as u64; count = count.saturating_sub(len); curpos += len; - trace!("sending {} bytes", len); + trace!("sending {len} bytes"); tx.send(buf).await; } } @@ -337,7 +333,7 @@ impl DavInner { let dirent = match dirent { Ok(dirent) => dirent, Err(e) => { - trace!("next dir entry error happened. Skipping {:?}", e); + trace!("next dir entry error happened. Skipping {e:?}"); continue; } }; @@ -451,8 +447,10 @@ impl DavInner { false => "[DIR] ".to_string(), }; let name = htmlescape::encode_minimal(&dirent.name); - let s = format!("{}{}{}", - dirent.path, name, modified, size); + let s = format!( + "{}{}{}", + dirent.path, name, modified, size + ); tx.send(Bytes::from(s)).await; } @@ -506,7 +504,7 @@ fn display_path(path: &DavPath) -> String { if idx == dpath_segs.len() - 1 { dpath.push_str(&dseg); } else { - dpath.push_str(&format!("{}/", upath, dseg)); + dpath.push_str(&format!("{dseg}/")); } } diff --git a/src/handle_lock.rs b/src/handle_lock.rs index b9bc8a7..552e3ae 100644 --- a/src/handle_lock.rs +++ b/src/handle_lock.rs @@ -343,7 +343,7 @@ fn build_lock_prop(lock: &DavLock, full: bool) -> Element { actlock.push_element(lockroot); if let Some(ref o) = lock.owner { - actlock.push_element(o.clone()); + actlock.push_element(*o.clone()); } if !full { diff --git a/src/handle_options.rs b/src/handle_options.rs index 568b389..6126c20 100644 --- a/src/handle_options.rs +++ b/src/handle_options.rs @@ -2,7 +2,7 @@ use headers::HeaderMapExt; use http::{Request, Response}; use crate::body::Body; -use crate::util::{dav_method, DavMethod}; +use crate::util::{DavMethod, dav_method}; use crate::{DavInner, DavResult}; impl DavInner { diff --git a/src/handle_props.rs b/src/handle_props.rs index 46ed2cb..78ea8cf 100644 --- a/src/handle_props.rs +++ b/src/handle_props.rs @@ -3,15 +3,15 @@ use std::collections::HashMap; use std::convert::TryFrom; use std::io::{self, Cursor}; -use futures_util::{future::BoxFuture, FutureExt, StreamExt}; +use futures_util::{FutureExt, StreamExt, future::BoxFuture}; use headers::HeaderMapExt; use http::{Request, Response, StatusCode}; use crate::xmltree_ext::*; +use xml::EmitterConfig; use xml::common::XmlVersion; use xml::writer::EventWriter; use xml::writer::XmlEvent as XmlWEvent; -use xml::EmitterConfig; use xmltree::{Element, XMLNode}; use crate::async_stream::AsyncStream; @@ -200,7 +200,7 @@ impl DavInner { } }; - trace!("propfind: type request: {}", name); + trace!("propfind: type request: {name}"); let mut pw = PropWriter::new( req, @@ -248,7 +248,7 @@ impl DavInner { Ok(entries) => entries, Err(e) => { // if we cannot read_dir, just skip it. - error!("read_dir error {:?}", e); + error!("read_dir error {e:?}"); return Ok(()); } }; @@ -257,7 +257,7 @@ impl DavInner { let dirent = match dirent { Ok(dirent) => dirent, Err(e) => { - trace!("next dir entry error happened. Skipping {:?}", e); + trace!("next dir entry error happened. Skipping {e:?}"); continue; } }; @@ -267,7 +267,7 @@ impl DavInner { let meta = match dirent.metadata().await { Ok(meta) => meta, Err(e) => { - trace!("metadata error on {}. Skipping {:?}", npath, e); + trace!("metadata error on {npath}. Skipping {e:?}"); continue; } }; @@ -301,10 +301,10 @@ impl DavInner { return StatusCode::CONFLICT; } // FIXME only here to make "litmus" happy, really... - if let Some(s) = prop.get_text() { - if davheaders::ContentLanguage::try_from(s.as_ref()).is_err() { - return StatusCode::CONFLICT; - } + if let Some(s) = prop.get_text() + && davheaders::ContentLanguage::try_from(s.as_ref()).is_err() + { + return StatusCode::CONFLICT; } if can_deadprop { StatusCode::CONTINUE @@ -700,10 +700,10 @@ impl PropWriter { // use ctime instead - apache seems to do this. if let Ok(ctime) = meta.status_changed() { let mut time = ctime; - if let Ok(mtime) = meta.modified() { - if mtime < ctime { - time = mtime; - } + if let Ok(mtime) = meta.modified() + && mtime < ctime + { + time = mtime; } let tm = systemtime_to_rfc3339_without_nanosecond(time); return self.build_elem(docontent, pfx, prop, tm); @@ -768,7 +768,7 @@ impl PropWriter { let used = if self.useragent.contains("WebDAVFS") { // Need this on MacOs, otherwise the value is off // by a factor of 10 or so .. ?!?!!? - format!("{:014}", used) + format!("{used:014}") } else { used.to_string() }; @@ -780,11 +780,11 @@ impl PropWriter { } Some(NS_APACHE_URI) => { pfx = "A"; - if prop.name.as_str() == "executable" { - if let Ok(x) = meta.executable() { - let b = if x { "T" } else { "F" }; - return self.build_elem(docontent, pfx, prop, b); - } + if prop.name.as_str() == "executable" + && let Ok(x) = meta.executable() + { + let b = if x { "T" } else { "F" }; + return self.build_elem(docontent, pfx, prop, b); } } Some(NS_MS_URI) => { @@ -798,10 +798,10 @@ impl PropWriter { // use ctime instead - apache seems to do this. if let Ok(ctime) = meta.status_changed() { let mut time = ctime; - if let Ok(mtime) = meta.modified() { - if mtime < ctime { - time = mtime; - } + if let Ok(mtime) = meta.modified() + && mtime < ctime + { + time = mtime; } let tm = systemtime_to_httpdate(time); return self.build_elem(docontent, pfx, prop, tm); @@ -836,7 +836,7 @@ impl PropWriter { // modification. attr |= 0x0020; } - return self.build_elem(docontent, pfx, prop, format!("{:08x}", attr)); + return self.build_elem(docontent, pfx, prop, format!("{attr:08x}")); } _ => {} } @@ -850,13 +850,13 @@ impl PropWriter { { // asking for a specific property. let dprop = element_to_davprop(prop); - if let Ok(xml) = self.fs.get_prop(path, dprop, &self.credentials).await { - if let Ok(e) = Element::parse(Cursor::new(xml)) { - return Ok(StatusElement { - status: StatusCode::OK, - element: e, - }); - } + if let Ok(xml) = self.fs.get_prop(path, dprop, &self.credentials).await + && let Ok(e) = Element::parse(Cursor::new(xml)) + { + return Ok(StatusElement { + status: StatusCode::OK, + element: e, + }); } } let prop = if !pfx.is_empty() { @@ -896,12 +896,11 @@ impl PropWriter { // and list the dead properties as well. if (self.name == "propname" || self.name == "allprop") && self.fs.have_props(path, &self.credentials).await + && let Ok(v) = self.fs.get_props(path, do_content, &self.credentials).await { - if let Ok(v) = self.fs.get_props(path, do_content, &self.credentials).await { - v.into_iter() - .map(davprop_to_element) - .for_each(|e| add_sc_elem(&mut props, StatusCode::OK, e)); - } + v.into_iter() + .map(davprop_to_element) + .for_each(|e| add_sc_elem(&mut props, StatusCode::OK, e)); } self.write_propresponse(path, props) diff --git a/src/handle_put.rs b/src/handle_put.rs index 11a8d6f..c24b60f 100644 --- a/src/handle_put.rs +++ b/src/handle_put.rs @@ -49,7 +49,7 @@ where }, } } else { - io::Error::new(io::ErrorKind::Other, err) + io::Error::other(err) } } diff --git a/src/localfs.rs b/src/localfs.rs index 363de1d..b3c79d4 100644 --- a/src/localfs.rs +++ b/src/localfs.rs @@ -17,13 +17,13 @@ use std::os::unix::{ use std::os::windows::prelude::*; use std::path::{Path, PathBuf}; use std::pin::Pin; -use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::Arc; +use std::sync::atomic::{AtomicU32, Ordering}; use std::task::{Context, Poll}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; use bytes::{Buf, Bytes, BytesMut}; -use futures_util::{future, future::BoxFuture, FutureExt, Stream}; +use futures_util::{FutureExt, Stream, future, future::BoxFuture}; use pin_utils::pin_mut; use tokio::task; @@ -488,7 +488,7 @@ fn read_batch( return ReadDirBatch { buffer, iterator: None, - } + }; } }; let _guard = match do_meta { @@ -560,7 +560,7 @@ impl Stream for LocalFsReadDir { this.fut.take(); if let Some(ref mut nb) = this.dir_cache { batch.buffer.iter().for_each(|e| { - if let Ok(ref e) = e { + if let Ok(e) = e { nb.add(e.entry.file_name()); } }); @@ -631,7 +631,7 @@ impl LocalFsDirEntry { } impl DavDirEntry for LocalFsDirEntry { - fn metadata(&self) -> FsFuture> { + fn metadata(&'_ self) -> FsFuture<'_, Box> { match self.meta { Meta::Data(ref meta) => { let m = match meta { @@ -661,21 +661,21 @@ impl DavDirEntry for LocalFsDirEntry { self.entry.file_name().to_str().unwrap().as_bytes().to_vec() } - fn is_dir(&self) -> FsFuture { + fn is_dir(&'_ self) -> FsFuture<'_, bool> { Box::pin(self.is_a(Is::Dir)) } - fn is_file(&self) -> FsFuture { + fn is_file(&'_ self) -> FsFuture<'_, bool> { Box::pin(self.is_a(Is::File)) } - fn is_symlink(&self) -> FsFuture { + fn is_symlink(&'_ self) -> FsFuture<'_, bool> { Box::pin(self.is_a(Is::Symlink)) } } impl DavFile for LocalFsFile { - fn metadata(&mut self) -> FsFuture> { + fn metadata(&'_ mut self) -> FsFuture<'_, Box> { async move { let file = self.0.take().unwrap(); let (meta, file) = blocking(move || (file.metadata(), file)).await; @@ -685,7 +685,7 @@ impl DavFile for LocalFsFile { .boxed() } - fn write_bytes(&mut self, buf: Bytes) -> FsFuture<()> { + fn write_bytes(&'_ mut self, buf: Bytes) -> FsFuture<'_, ()> { async move { let mut file = self.0.take().unwrap(); let (res, file) = blocking(move || (file.write_all(&buf), file)).await; @@ -695,7 +695,7 @@ impl DavFile for LocalFsFile { .boxed() } - fn write_buf(&mut self, mut buf: Box) -> FsFuture<()> { + fn write_buf(&'_ mut self, mut buf: Box) -> FsFuture<'_, ()> { async move { let mut file = self.0.take().unwrap(); let (res, file) = blocking(move || { @@ -715,7 +715,7 @@ impl DavFile for LocalFsFile { .boxed() } - fn read_bytes(&mut self, count: usize) -> FsFuture { + fn read_bytes(&'_ mut self, count: usize) -> FsFuture<'_, Bytes> { async move { let mut file = self.0.take().unwrap(); let (res, file) = blocking(move || { @@ -736,7 +736,7 @@ impl DavFile for LocalFsFile { .boxed() } - fn seek(&mut self, pos: SeekFrom) -> FsFuture { + fn seek(&'_ mut self, pos: SeekFrom) -> FsFuture<'_, u64> { async move { let mut file = self.0.take().unwrap(); let (res, file) = blocking(move || (file.seek(pos), file)).await; @@ -746,7 +746,7 @@ impl DavFile for LocalFsFile { .boxed() } - fn flush(&mut self) -> FsFuture<()> { + fn flush(&'_ mut self) -> FsFuture<'_, ()> { async move { let mut file = self.0.take().unwrap(); let (res, file) = blocking(move || (file.flush(), file)).await; diff --git a/src/localfs_macos.rs b/src/localfs_macos.rs index 286eaeb..5aa0f8b 100644 --- a/src/localfs_macos.rs +++ b/src/localfs_macos.rs @@ -13,8 +13,8 @@ use std::num::NonZeroUsize; #[cfg(unix)] use std::os::unix::ffi::OsStrExt; use std::path::{Path, PathBuf}; -use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; +use std::sync::atomic::{AtomicUsize, Ordering}; use std::thread; use std::time::{Duration, SystemTime, UNIX_EPOCH}; @@ -63,7 +63,7 @@ impl DUCache { let now = SystemTime::now(); while let Some((_k, e)) = cache.peek_lru() { if let Ok(age) = now.duration_since(e.time) { - trace!(target: "webdav_cache", "DUCache: purge check {:?}", _k); + trace!(target: "webdav_cache", "DUCache: purge check {_k:?}"); if age.as_secs() <= DU_CACHE_MAX_AGE { break; } @@ -100,7 +100,7 @@ impl DUCache { match cache.peek(&dir) { Some(t) => (t.dir_id, t.dir_modtime), None => { - trace!(target: "webdav_cache", "DUCache::negative({:?}): parent not in cache", path); + trace!(target: "webdav_cache", "DUCache::negative({path:?}): parent not in cache"); return false; } } @@ -114,7 +114,7 @@ impl DUCache { }; let mut cache = self.cache.lock(); if !valid { - trace!(target: "webdav_cache", "DUCache::negative({:?}): parent in cache but stale", path); + trace!(target: "webdav_cache", "DUCache::negative({path:?}): parent in cache but stale"); cache.pop(&dir); return false; } @@ -128,7 +128,7 @@ impl DUCache { t.dir_id != dir_id } None => { - trace!(target: "webdav_cache", "DUCache::negative({:?}): not in cache", path); + trace!(target: "webdav_cache", "DUCache::negative({path:?}): not in cache"); true } } @@ -156,20 +156,20 @@ impl DUCacheBuilder { // add a filename to the list we have #[cfg(unix)] pub fn add(&mut self, filename: OsString) { - if let Some(f) = Path::new(&filename).file_name() { - if f.as_bytes().starts_with(b"._") { - self.entries.push(filename); - } + if let Some(f) = Path::new(&filename).file_name() + && f.as_bytes().starts_with(b"._") + { + self.entries.push(filename); } } // add a filename to the list we have #[cfg(windows)] pub fn add(&mut self, filename: OsString) { - if let Some(f) = Path::new(&filename).file_name() { - if f.to_str().unwrap().as_bytes().starts_with(b"._") { - self.entries.push(filename); - } + if let Some(f) = Path::new(&filename).file_name() + && f.to_str().unwrap().as_bytes().starts_with(b"._") + { + self.entries.push(filename); } } diff --git a/src/localfs_windows.rs b/src/localfs_windows.rs index 7c48844..463851c 100644 --- a/src/localfs_windows.rs +++ b/src/localfs_windows.rs @@ -188,13 +188,13 @@ impl Cache { let now = d.as_secs(); let mut cache = CACHE.cache.lock(); while let Some((_k, e)) = cache.peek_lru() { - trace!(target: "webdav_cache", "Cache: purge check: {:?}", _k); + trace!(target: "webdav_cache", "Cache: purge check: {_k:?}"); if e.time + CACHE_MAX_AGE > now { break; } let _age = now - e.time; if let Some((_k, _)) = cache.pop_lru() { - trace!(target: "webdav_cache", "Cache: purging {:?} (age {})", _k, _age); + trace!(target: "webdav_cache", "Cache: purging {_k:?} (age {_age})"); } else { break; } diff --git a/src/ls.rs b/src/ls.rs index 27f9971..3def7a8 100644 --- a/src/ls.rs +++ b/src/ls.rs @@ -12,7 +12,7 @@ use std::fmt::Debug; use std::pin::Pin; use std::time::{Duration, SystemTime}; -use dyn_clone::{clone_trait_object, DynClone}; +use dyn_clone::{DynClone, clone_trait_object}; use futures_util::Future; use xmltree::Element; @@ -22,11 +22,11 @@ pub struct DavLock { /// Token. pub token: String, /// Path/ - pub path: DavPath, + pub path: Box, /// Principal. pub principal: Option, /// Owner. - pub owner: Option, + pub owner: Option>, /// When the lock turns stale (absolute). pub timeout_at: Option, /// When the lock turns stale (relative). @@ -44,43 +44,43 @@ pub trait DavLockSystem: Debug + Send + Sync + DynClone { /// Lock a node. Returns `Ok(new_lock)` if succeeded, /// or `Err(conflicting_lock)` if failed. fn lock( - &self, + &'_ self, path: &DavPath, principal: Option<&str>, owner: Option<&Element>, timeout: Option, shared: bool, deep: bool, - ) -> LsFuture>; + ) -> LsFuture<'_, Result>; /// Unlock a node. Returns `Ok(())` if succeeded, `Err (())` if failed /// (because lock doesn't exist) - fn unlock(&self, path: &DavPath, token: &str) -> LsFuture>; + fn unlock(&'_ self, path: &DavPath, token: &str) -> LsFuture<'_, Result<(), ()>>; /// Refresh lock. Returns updated lock if succeeded. fn refresh( - &self, + &'_ self, path: &DavPath, token: &str, timeout: Option, - ) -> LsFuture>; + ) -> LsFuture<'_, Result>; /// 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, + &'_ self, path: &DavPath, principal: Option<&str>, ignore_principal: bool, deep: bool, submitted_tokens: Vec<&str>, - ) -> LsFuture>; + ) -> LsFuture<'_, Result<(), DavLock>>; /// Find and return all locks that cover a given path. - fn discover(&self, path: &DavPath) -> LsFuture>; + fn discover(&'_ self, path: &DavPath) -> LsFuture<'_, Vec>; /// Delete all locks at this path and below (after MOVE or DELETE) - fn delete(&self, path: &DavPath) -> LsFuture>; + fn delete(&'_ self, path: &DavPath) -> LsFuture<'_, Result<(), ()>>; } clone_trait_object! {DavLockSystem} diff --git a/src/memfs.rs b/src/memfs.rs index 18236d3..6811314 100644 --- a/src/memfs.rs +++ b/src/memfs.rs @@ -13,9 +13,8 @@ use std::time::SystemTime; use bytes::{Buf, Bytes}; use futures_util::{ - future, + StreamExt, future, future::{BoxFuture, FutureExt}, - StreamExt, }; use http::StatusCode; @@ -173,7 +172,7 @@ impl DavFileSystem for MemFs { fn create_dir<'a>(&'a self, path: &'a DavPath) -> FsFuture<'a, ()> { async move { - trace!("FS: create_dir {:?}", path); + trace!("FS: create_dir {path:?}"); let tree = &mut *self.tree.lock().unwrap(); let path = path.as_bytes(); let parent_id = tree.lookup_parent(path)?; @@ -336,7 +335,7 @@ fn cloneprop(p: &DavProp) -> DavProp { } impl DavDirEntry for MemFsDirEntry { - fn metadata(&self) -> FsFuture> { + fn metadata(&'_ self) -> FsFuture<'_, Box> { let meta = (*self).clone(); Box::pin(future::ok(Box::new(meta) as Box)) } @@ -347,7 +346,7 @@ impl DavDirEntry for MemFsDirEntry { } impl DavFile for MemFsFile { - fn metadata(&mut self) -> FsFuture> { + fn metadata(&'_ mut self) -> FsFuture<'_, Box> { async move { let tree = &*self.tree.lock().unwrap(); let node = tree.get_node(self.node_id)?; @@ -357,7 +356,7 @@ impl DavFile for MemFsFile { .boxed() } - fn read_bytes(&mut self, count: usize) -> FsFuture { + fn read_bytes(&'_ mut self, count: usize) -> FsFuture<'_, Bytes> { async move { let tree = &*self.tree.lock().unwrap(); let node = tree.get_node(self.node_id)?; @@ -378,7 +377,7 @@ impl DavFile for MemFsFile { .boxed() } - fn write_bytes(&mut self, buf: Bytes) -> FsFuture<()> { + fn write_bytes(&'_ mut self, buf: Bytes) -> FsFuture<'_, ()> { async move { let tree = &mut *self.tree.lock().unwrap(); let node = tree.get_node_mut(self.node_id)?; @@ -397,7 +396,7 @@ impl DavFile for MemFsFile { .boxed() } - fn write_buf(&mut self, mut buf: Box) -> FsFuture<()> { + fn write_buf(&'_ mut self, mut buf: Box) -> FsFuture<'_, ()> { async move { let tree = &mut *self.tree.lock().unwrap(); let node = tree.get_node_mut(self.node_id)?; @@ -421,11 +420,11 @@ impl DavFile for MemFsFile { .boxed() } - fn flush(&mut self) -> FsFuture<()> { + fn flush(&'_ mut self) -> FsFuture<'_, ()> { future::ok(()).boxed() } - fn seek(&mut self, pos: SeekFrom) -> FsFuture { + fn seek(&'_ mut self, pos: SeekFrom) -> FsFuture<'_, u64> { async move { let (start, offset): (u64, i64) = match pos { SeekFrom::Start(npos) => { diff --git a/src/memls.rs b/src/memls.rs index fa5200f..c82f9f3 100644 --- a/src/memls.rs +++ b/src/memls.rs @@ -10,7 +10,7 @@ use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::time::{Duration, SystemTime}; -use futures_util::{future, FutureExt}; +use futures_util::{FutureExt, future}; use uuid::Uuid; use xmltree::Element; @@ -45,19 +45,19 @@ impl MemLs { impl DavLockSystem for MemLs { fn lock( - &self, + &'_ self, path: &DavPath, principal: Option<&str>, owner: Option<&Element>, timeout: Option, shared: bool, deep: bool, - ) -> LsFuture> { + ) -> LsFuture<'_, Result> { let inner = &mut *self.0.lock().unwrap(); // any locks in the path? let rc = check_locks_to_path(&inner.tree, path, None, true, &Vec::new(), shared); - trace!("lock: check_locks_to_path: {:?}", rc); + trace!("lock: check_locks_to_path: {rc:?}"); if let Err(err) = rc { return future::ready(Err(err)).boxed(); } @@ -65,7 +65,7 @@ impl DavLockSystem for MemLs { // if it's a deep lock we need to check if there are locks furter along the path. if deep { let rc = check_locks_from_path(&inner.tree, path, None, true, &Vec::new(), shared); - trace!("lock: check_locks_from_path: {:?}", rc); + trace!("lock: check_locks_from_path: {rc:?}"); if let Err(err) = rc { return future::ready(Err(err)).boxed(); } @@ -76,9 +76,9 @@ impl DavLockSystem for MemLs { let timeout_at = timeout.map(|d| SystemTime::now() + d); let lock = DavLock { token: Uuid::new_v4().urn().to_string(), - path: path.clone(), + path: Box::new(path.clone()), principal: principal.map(|s| s.to_string()), - owner: owner.cloned(), + owner: owner.map(|o| Box::new(o.clone())), timeout_at, timeout, shared, @@ -90,11 +90,11 @@ impl DavLockSystem for MemLs { future::ready(Ok(lock)).boxed() } - fn unlock(&self, path: &DavPath, token: &str) -> LsFuture> { + fn unlock(&'_ self, path: &DavPath, token: &str) -> LsFuture<'_, Result<(), ()>> { let inner = &mut *self.0.lock().unwrap(); let node_id = match lookup_lock(&inner.tree, path, token) { None => { - trace!("unlock: {} not found at {}", token, path); + trace!("unlock: {token} not found at {path}"); return future::ready(Err(())).boxed(); } Some(n) => n, @@ -112,12 +112,12 @@ impl DavLockSystem for MemLs { } fn refresh( - &self, + &'_ self, path: &DavPath, token: &str, timeout: Option, - ) -> LsFuture> { - trace!("refresh lock {}", token); + ) -> LsFuture<'_, Result> { + trace!("refresh lock {token}"); let inner = &mut *self.0.lock().unwrap(); let node_id = match lookup_lock(&inner.tree, path, token) { None => { @@ -136,13 +136,13 @@ impl DavLockSystem for MemLs { } fn check( - &self, + &'_ self, path: &DavPath, principal: Option<&str>, ignore_principal: bool, deep: bool, submitted_tokens: Vec<&str>, - ) -> LsFuture> { + ) -> LsFuture<'_, Result<(), DavLock>> { let inner = &*self.0.lock().unwrap(); let _st = submitted_tokens.clone(); let rc = check_locks_to_path( @@ -153,7 +153,7 @@ impl DavLockSystem for MemLs { &submitted_tokens, false, ); - trace!("check: check_lock_to_path: {:?}: {:?}", _st, rc); + trace!("check: check_lock_to_path: {_st:?}: {rc:?}"); if let Err(err) = rc { return future::ready(Err(err)).boxed(); } @@ -168,7 +168,7 @@ impl DavLockSystem for MemLs { &submitted_tokens, false, ); - trace!("check: check_locks_from_path: {:?}", rc); + trace!("check: check_locks_from_path: {rc:?}"); if let Err(err) = rc { return future::ready(Err(err)).boxed(); } @@ -176,12 +176,12 @@ impl DavLockSystem for MemLs { future::ready(Ok(())).boxed() } - fn discover(&self, path: &DavPath) -> LsFuture> { + fn discover(&'_ self, path: &DavPath) -> LsFuture<'_, Vec> { let inner = &*self.0.lock().unwrap(); future::ready(list_locks(&inner.tree, path)).boxed() } - fn delete(&self, path: &DavPath) -> LsFuture> { + fn delete(&'_ self, path: &DavPath) -> LsFuture<'_, Result<(), ()>> { let inner = &mut *self.0.lock().unwrap(); if let Some(node_id) = lookup_node(&inner.tree, path) { inner.tree.delete_subtree(node_id).ok(); @@ -242,10 +242,8 @@ fn check_locks_to_path( } // return conflicting lock on error. - if !holds_lock { - if let Some(first_lock_seen) = first_lock_seen { - return Err(first_lock_seen.to_owned()); - } + if !holds_lock && let Some(first_lock_seen) = first_lock_seen { + return Err(first_lock_seen.to_owned()); } Ok(()) @@ -326,7 +324,7 @@ fn get_or_create_path_node<'a>(tree: &'a mut Tree, path: &DavPath) -> &'a mut Ve // Find lock in path. fn lookup_lock(tree: &Tree, path: &DavPath, token: &str) -> Option { - trace!("lookup_lock: {}", token); + trace!("lookup_lock: {token}"); let mut node_id = tree::ROOT_ID; for seg in path_to_segs(path, true) { diff --git a/src/multierror.rs b/src/multierror.rs index 5ff37ec..60eca72 100644 --- a/src/multierror.rs +++ b/src/multierror.rs @@ -3,16 +3,16 @@ use std::io; use futures_util::{Stream, StreamExt}; use http::{Response, StatusCode}; +use xml::EmitterConfig; use xml::common::XmlVersion; use xml::writer::EventWriter; use xml::writer::XmlEvent as XmlWEvent; -use xml::EmitterConfig; +use crate::DavError; use crate::async_stream::AsyncStream; use crate::body::Body; use crate::davpath::DavPath; use crate::util::MemBuffer; -use crate::DavError; type Sender = crate::async_stream::Sender<(DavPath, StatusCode), DavError>; @@ -53,7 +53,7 @@ fn write_response(w: &mut XmlWriter, path: &DavPath, sc: StatusCode) -> Result<( w.write(XmlWEvent::start_element("D:response"))?; let p = path.with_prefix().as_url_string(); write_elem(w, "D:href", &p)?; - write_elem(w, "D:status", &format!("HTTP/1.1 {}", sc))?; + write_elem(w, "D:status", &format!("HTTP/1.1 {sc}"))?; w.write(XmlWEvent::end_element())?; Ok(()) } diff --git a/src/util.rs b/src/util.rs index 0aecb42..1c660c7 100644 --- a/src/util.rs +++ b/src/util.rs @@ -7,9 +7,9 @@ use http::method::InvalidMethod; use time::format_description::well_known::Rfc3339; use time::macros::offset; +use crate::DavResult; use crate::body::Body; use crate::errors::DavError; -use crate::DavResult; /// HTTP Methods supported by DavHandler. #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] diff --git a/src/warp.rs b/src/warp.rs index 5b7e629..cb6740e 100644 --- a/src/warp.rs +++ b/src/warp.rs @@ -10,12 +10,12 @@ use std::convert::Infallible; use std::path::Path; use warp::{ + Filter, Reply, filters::BoxedFilter, http::{HeaderMap, Method}, - Filter, Reply, }; -use crate::{body::Body, DavHandler}; +use crate::{DavHandler, body::Body}; #[cfg(any(docsrs, feature = "localfs"))] use crate::{fakels::FakeLs, localfs::LocalFs}; diff --git a/src/xmltree_ext.rs b/src/xmltree_ext.rs index a957815..f66f2df 100644 --- a/src/xmltree_ext.rs +++ b/src/xmltree_ext.rs @@ -1,10 +1,10 @@ use std::borrow::Cow; use std::io::{Read, Write}; +use xml::EmitterConfig; use xml::common::XmlVersion; use xml::writer::EventWriter; use xml::writer::XmlEvent as XmlWEvent; -use xml::EmitterConfig; use xmltree::{self, Element, XMLNode};