This commit is contained in:
sxyazi 2025-08-28 22:48:56 +08:00
parent f55c4f662f
commit 9532ffe3a8
No known key found for this signature in database
11 changed files with 35 additions and 36 deletions

View file

@ -53,7 +53,7 @@ impl Create {
FilesOp::Deleting(parent.into(), [urn.into()].into()).emit(); FilesOp::Deleting(parent.into(), [urn.into()].into()).emit();
provider::create(&new).await?; provider::create(&new).await?;
} else if let Some(parent) = new.parent() { } else if let Some(parent) = new.parent() {
provider::create_dir_all(&parent).await.ok(); provider::create_dir_all(parent).await.ok();
ok_or_not_found(provider::remove_file(&new).await)?; ok_or_not_found(provider::remove_file(&new).await)?;
provider::create(&new).await?; provider::create(&new).await?;
} else { } else {

View file

@ -275,16 +275,16 @@ mod tests {
let child1 = url("/parent/child1"); let child1 = url("/parent/child1");
let child2 = url("/parent/child2"); let child2 = url("/parent/child2");
let child3 = url("/parent/child3"); let child3 = url("/parent/child3");
assert_eq!(3, s.add_same([&child1, &child2, &child3])); assert_eq!(3, s.add_same([child1, child2, child3]));
assert!(s.remove(&child1)); assert!(s.remove(child1));
assert_eq!(s.inner.len(), 2); assert_eq!(s.inner.len(), 2);
assert!(!s.parents.is_empty()); assert!(!s.parents.is_empty());
assert!(s.remove(&child2)); assert!(s.remove(child2));
assert!(!s.parents.is_empty()); assert!(!s.parents.is_empty());
assert!(s.remove(&child3)); assert!(s.remove(child3));
assert!(s.inner.is_empty()); assert!(s.inner.is_empty());
assert!(s.parents.is_empty()); assert!(s.parents.is_empty());
} }

View file

@ -8,10 +8,7 @@ pub fn clean_url<'a>(url: impl Into<UrlCow<'a>>) -> UrlBuf {
clean_path_impl(&cow.loc(), cow.loc().base().count(), cow.loc().trail().count()); clean_path_impl(&cow.loc(), cow.loc().base().count(), cow.loc().trail().count());
let loc = LocBuf::with(path, uri, urn).expect("Failed to create Loc from cleaned path"); let loc = LocBuf::with(path, uri, urn).expect("Failed to create Loc from cleaned path");
match cow { UrlBuf { loc, scheme: cow.into_scheme().into() }
UrlCow::Borrowed { scheme, .. } => UrlBuf { loc, scheme: scheme.into() },
UrlCow::Owned { scheme, .. } => UrlBuf { loc, scheme },
}
} }
fn clean_path_impl(path: &Path, base: usize, trail: usize) -> (PathBuf, usize, usize) { fn clean_path_impl(path: &Path, base: usize, trail: usize) -> (PathBuf, usize, usize) {

View file

@ -77,7 +77,7 @@ impl File {
}; };
let src = if task.relative { let src = if task.relative {
path_relative_to(provider::canonicalize(&task.to.parent().unwrap()).await?.loc, &src)? path_relative_to(provider::canonicalize(task.to.parent().unwrap()).await?.loc, &src)?
} else { } else {
src src
}; };

View file

@ -1,6 +1,6 @@
use crate::{pool::InternStr, scheme::Scheme}; use crate::{pool::InternStr, scheme::Scheme};
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub enum SchemeRef<'a> { pub enum SchemeRef<'a> {
#[default] #[default]
Regular, Regular,

View file

@ -1,6 +1,8 @@
use std::hash::{Hash, Hasher};
use crate::{pool::Symbol, scheme::SchemeRef}; use crate::{pool::Symbol, scheme::SchemeRef};
#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Clone, Debug, Default, Eq, PartialEq)]
pub enum Scheme { pub enum Scheme {
#[default] #[default]
Regular, Regular,
@ -12,6 +14,10 @@ pub enum Scheme {
Sftp(Symbol<str>), Sftp(Symbol<str>),
} }
impl Hash for Scheme {
fn hash<H: Hasher>(&self, state: &mut H) { self.as_ref().hash(state); }
}
impl Scheme { impl Scheme {
#[inline] #[inline]
pub fn as_ref(&self) -> SchemeRef<'_> { self.into() } pub fn as_ref(&self) -> SchemeRef<'_> { self.into() }

View file

@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
use crate::{loc::LocBuf, pool::Pool, scheme::{Scheme, SchemeRef}, url::{Components, Display, Encode, EncodeTilded, Uri, Url, UrlCow, Urn}}; use crate::{loc::LocBuf, pool::Pool, scheme::{Scheme, SchemeRef}, url::{Components, Display, Encode, EncodeTilded, Uri, Url, UrlCow, Urn}};
#[derive(Clone, Default, Eq, Ord, PartialOrd, PartialEq, Hash)] #[derive(Clone, Default, Eq, Hash, PartialEq)]
pub struct UrlBuf { pub struct UrlBuf {
pub loc: LocBuf, pub loc: LocBuf,
pub scheme: Scheme, pub scheme: Scheme,

View file

@ -2,7 +2,7 @@ use std::{borrow::Cow, ffi::{OsStr, OsString}, iter::FusedIterator, ops::Not, pa
use crate::{loc::Loc, scheme::{Scheme, SchemeRef}, url::{Encode, Url, UrlBuf, UrlCow}}; use crate::{loc::Loc, scheme::{Scheme, SchemeRef}, url::{Encode, Url, UrlBuf, UrlCow}};
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Component<'a> { pub enum Component<'a> {
Scheme(SchemeRef<'a>), Scheme(SchemeRef<'a>),
Prefix(PrefixComponent<'a>), Prefix(PrefixComponent<'a>),

View file

@ -3,12 +3,12 @@ use std::{borrow::Cow, path::{Path, PathBuf}};
use anyhow::Result; use anyhow::Result;
use percent_encoding::percent_decode; use percent_encoding::percent_decode;
use crate::{IntoOsStr, loc::{Loc, LocBuf}, scheme::{Scheme, SchemeCow, SchemeRef}, url::{Components, Url, UrlBuf, Urn}}; use crate::{IntoOsStr, loc::{Loc, LocBuf}, scheme::{SchemeCow, SchemeRef}, url::{Components, Url, UrlBuf, Urn}};
#[derive(Debug)] #[derive(Debug)]
pub enum UrlCow<'a> { pub enum UrlCow<'a> {
Borrowed { loc: Loc<'a>, scheme: SchemeCow<'a> }, Borrowed { loc: Loc<'a>, scheme: SchemeCow<'a> },
Owned { loc: LocBuf, scheme: Scheme }, Owned { loc: LocBuf, scheme: SchemeCow<'a> },
} }
impl Default for UrlCow<'_> { impl Default for UrlCow<'_> {
@ -26,7 +26,7 @@ impl<'a> From<&'a UrlBuf> for UrlCow<'a> {
} }
impl From<UrlBuf> for UrlCow<'_> { impl From<UrlBuf> for UrlCow<'_> {
fn from(value: UrlBuf) -> Self { Self::Owned { loc: value.loc, scheme: value.scheme } } fn from(value: UrlBuf) -> Self { Self::Owned { loc: value.loc, scheme: value.scheme.into() } }
} }
impl<'a> From<&'a UrlCow<'a>> for Url<'a> { impl<'a> From<&'a UrlCow<'a>> for Url<'a> {
@ -52,9 +52,9 @@ impl<'a> TryFrom<&'a [u8]> for UrlCow<'a> {
(Cow::Borrowed(p), Some((uri, urn))) => { (Cow::Borrowed(p), Some((uri, urn))) => {
Self::Borrowed { loc: Loc::with(p, uri, urn)?, scheme } Self::Borrowed { loc: Loc::with(p, uri, urn)?, scheme }
} }
(Cow::Owned(p), None) => Self::Owned { loc: LocBuf::from(p), scheme: scheme.into() }, (Cow::Owned(p), None) => Self::Owned { loc: LocBuf::from(p), scheme },
(Cow::Owned(p), Some((uri, urn))) => { (Cow::Owned(p), Some((uri, urn))) => {
Self::Owned { loc: LocBuf::with(p, uri, urn)?, scheme: scheme.into() } Self::Owned { loc: LocBuf::with(p, uri, urn)?, scheme }
} }
}) })
} }
@ -98,7 +98,7 @@ impl PartialEq<UrlBuf> for UrlCow<'_> {
fn eq(&self, other: &UrlBuf) -> bool { self.as_url() == other.as_url() } fn eq(&self, other: &UrlBuf) -> bool { self.as_url() == other.as_url() }
} }
impl UrlCow<'_> { impl<'a> UrlCow<'a> {
#[inline] #[inline]
pub fn loc(&self) -> Loc<'_> { pub fn loc(&self) -> Loc<'_> {
match self { match self {
@ -127,7 +127,15 @@ impl UrlCow<'_> {
pub fn into_owned(self) -> UrlBuf { pub fn into_owned(self) -> UrlBuf {
match self { match self {
UrlCow::Borrowed { loc, scheme } => UrlBuf { loc: loc.into(), scheme: scheme.into() }, UrlCow::Borrowed { loc, scheme } => UrlBuf { loc: loc.into(), scheme: scheme.into() },
UrlCow::Owned { loc, scheme } => UrlBuf { loc, scheme }, UrlCow::Owned { loc, scheme } => UrlBuf { loc, scheme: scheme.into() },
}
}
#[inline]
pub fn into_scheme(self) -> SchemeCow<'a> {
match self {
UrlCow::Borrowed { scheme, .. } => scheme,
UrlCow::Owned { scheme, .. } => scheme,
} }
} }

View file

@ -9,8 +9,8 @@ pub struct Encode<'a> {
scheme: SchemeRef<'a>, scheme: SchemeRef<'a>,
} }
impl<'a> From<&'a Url<'a>> for Encode<'a> { impl<'a> From<Url<'a>> for Encode<'a> {
fn from(url: &'a Url<'a>) -> Self { Self::new(url.loc, url.scheme) } fn from(url: Url<'a>) -> Self { Self::new(url.loc, url.scheme) }
} }
impl<'a> From<&'a UrlBuf> for Encode<'a> { impl<'a> From<&'a UrlBuf> for Encode<'a> {
@ -78,10 +78,6 @@ pub struct EncodeTilded<'a> {
scheme: SchemeRef<'a>, scheme: SchemeRef<'a>,
} }
impl<'a> From<&'a Url<'a>> for EncodeTilded<'a> {
fn from(url: &'a Url<'a>) -> Self { Self { loc: url.loc, scheme: url.scheme } }
}
impl<'a> From<&'a UrlBuf> for EncodeTilded<'a> { impl<'a> From<&'a UrlBuf> for EncodeTilded<'a> {
fn from(url: &'a UrlBuf) -> Self { Self { loc: url.loc.as_loc(), scheme: url.scheme.as_ref() } } fn from(url: &'a UrlBuf) -> Self { Self { loc: url.loc.as_loc(), scheme: url.scheme.as_ref() } }
} }

View file

@ -10,11 +10,6 @@ pub struct Url<'a> {
pub scheme: SchemeRef<'a>, pub scheme: SchemeRef<'a>,
} }
// TODO: remove
impl<'a> From<&'a Url<'a>> for Url<'a> {
fn from(value: &'a Url) -> Self { Self { loc: value.loc.as_loc(), scheme: value.scheme } }
}
impl<'a> From<&'a UrlBuf> for Url<'a> { impl<'a> From<&'a UrlBuf> for Url<'a> {
fn from(value: &'a UrlBuf) -> Self { fn from(value: &'a UrlBuf) -> Self {
Self { loc: value.loc.as_loc(), scheme: value.scheme.as_ref() } Self { loc: value.loc.as_loc(), scheme: value.scheme.as_ref() }
@ -41,7 +36,7 @@ impl Debug for Url<'_> {
if self.scheme == SchemeRef::Regular { if self.scheme == SchemeRef::Regular {
write!(f, "{}", self.loc.display()) write!(f, "{}", self.loc.display())
} else { } else {
write!(f, "{}{}", Encode::from(self), self.loc.display()) write!(f, "{}{}", Encode::from(*self), self.loc.display())
} }
} }
} }
@ -69,9 +64,6 @@ impl<'a> Url<'a> {
#[inline] #[inline]
pub fn has_root(self) -> bool { self.loc.has_root() } pub fn has_root(self) -> bool { self.loc.has_root() }
#[inline]
pub fn as_url(self) -> Url<'a> { self }
#[inline] #[inline]
pub fn to_owned(self) -> UrlBuf { self.into() } pub fn to_owned(self) -> UrlBuf { self.into() }