diff --git a/yazi-actor/src/cmp/trigger.rs b/yazi-actor/src/cmp/trigger.rs index d2e715ca..29f435b5 100644 --- a/yazi-actor/src/cmp/trigger.rs +++ b/yazi-actor/src/cmp/trigger.rs @@ -115,12 +115,12 @@ mod tests { fn test_split() { yazi_fs::init(); compare("foo", "", "foo"); - compare("foo\\", "foo\\", ""); - compare("foo\\bar", "foo\\", "bar"); - compare("foo\\bar\\", "foo\\bar\\", ""); - compare("C:\\", "C:\\", ""); - compare("C:\\foo", "C:\\", "foo"); - compare("C:\\foo\\", "C:\\foo\\", ""); - compare("C:\\foo\\bar", "C:\\foo\\", "bar"); + compare(r"foo\", r"foo\", ""); + compare(r"foo\bar", r"foo\", "bar"); + compare(r"foo\bar\", r"foo\bar\", ""); + compare(r"C:\", r"C:\", ""); + compare(r"C:\foo", r"C:\", "foo"); + compare(r"C:\foo\", r"C:\foo\", ""); + compare(r"C:\foo\bar", r"C:\foo\", "bar"); } } diff --git a/yazi-actor/src/lives/file.rs b/yazi-actor/src/lives/file.rs index 2de0a85b..11dce848 100644 --- a/yazi-actor/src/lives/file.rs +++ b/yazi-actor/src/lives/file.rs @@ -121,7 +121,7 @@ impl UserData for File { _ => 0u8, }) }); - methods.add_method("is_selected", |_, me, ()| Ok(me.tab.selected.contains_key(&me.url))); + methods.add_method("is_selected", |_, me, ()| Ok(me.tab.selected.contains(&me.url))); methods.add_method("found", |lua, me, ()| { lua.named_registry_value::("cx")?.borrow_scoped(|core: &yazi_core::Core| { let Some(finder) = &core.active().finder else { diff --git a/yazi-actor/src/lives/selected.rs b/yazi-actor/src/lives/selected.rs index dcab02b3..dd513b33 100644 --- a/yazi-actor/src/lives/selected.rs +++ b/yazi-actor/src/lives/selected.rs @@ -1,4 +1,3 @@ -use indexmap::IndexMap; use mlua::AnyUserData; use super::Lives; @@ -9,11 +8,11 @@ pub(super) struct Selected; impl Selected { #[inline] - pub(super) fn make(inner: &IndexMap) -> mlua::Result { + pub(super) fn make(inner: &yazi_core::tab::Selected) -> mlua::Result { let inner = PtrCell::from(inner); Lives::scoped_userdata(yazi_binding::Iter::new( - inner.as_static().keys().cloned().map(yazi_binding::Url::new), + inner.as_static().values().cloned().map(yazi_binding::Url::new), Some(inner.len()), )) } diff --git a/yazi-actor/src/mgr/copy.rs b/yazi-actor/src/mgr/copy.rs index d615d0f2..573aa94f 100644 --- a/yazi-actor/src/mgr/copy.rs +++ b/yazi-actor/src/mgr/copy.rs @@ -1,5 +1,4 @@ -// FIXME: VFS -use std::{ffi::OsString, path::Path}; +use std::ffi::OsString; use anyhow::{Result, bail}; use yazi_macro::{act, succ}; @@ -28,13 +27,24 @@ impl Actor for Copy { .peekable(); while let Some(u) = it.next() { - s.push(match opt.r#type.as_ref() { - "path" => opt.separator.transform(u), - "dirname" => opt.separator.transform(u.parent().unwrap_or(Path::new(""))), - "filename" => opt.separator.transform(u.name()), - "name_without_ext" => opt.separator.transform(u.file_stem().unwrap_or_default()), + match opt.r#type.as_ref() { + // TODO: rename to "url" + "path" => { + s.push(opt.separator.transform(&u.os_str())); + } + "dirname" => { + if let Some(p) = u.parent_url() { + s.push(opt.separator.transform(&p.os_str())); + } + } + "filename" => { + s.push(opt.separator.transform(u.name())); + } + "name_without_ext" => { + s.push(opt.separator.transform(u.file_stem().unwrap_or_default())); + } _ => bail!("Unknown copy type: {}", opt.r#type), - }); + }; if it.peek().is_some() { s.push("\n"); } @@ -42,7 +52,7 @@ impl Actor for Copy { // Copy the CWD path regardless even if the directory is empty if s.is_empty() && opt.r#type == "dirname" { - s.push(opt.separator.transform(cx.cwd())); + s.push(opt.separator.transform(&cx.cwd().os_str())); } futures::executor::block_on(CLIPBOARD.set(s)); diff --git a/yazi-actor/src/mgr/toggle_all.rs b/yazi-actor/src/mgr/toggle_all.rs index f79252c5..ec2d5101 100644 --- a/yazi-actor/src/mgr/toggle_all.rs +++ b/yazi-actor/src/mgr/toggle_all.rs @@ -23,8 +23,8 @@ impl Actor for ToggleAll { Some(true) => Right((vec![], opt.urls)), Some(false) if opt.urls.is_empty() => Left((it.collect(), vec![])), Some(false) => Right((opt.urls, vec![])), - None if opt.urls.is_empty() => Left(it.partition(|&u| tab.selected.contains_key(u))), - None => Right(opt.urls.into_iter().partition(|u| tab.selected.contains_key(u))), + None if opt.urls.is_empty() => Left(it.partition(|&u| tab.selected.contains(u))), + None => Right(opt.urls.into_iter().partition(|u| tab.selected.contains(u))), }; let warn = match either { diff --git a/yazi-actor/src/mgr/yank.rs b/yazi-actor/src/mgr/yank.rs index 2a96ec7f..a68368b8 100644 --- a/yazi-actor/src/mgr/yank.rs +++ b/yazi-actor/src/mgr/yank.rs @@ -2,7 +2,7 @@ use anyhow::Result; use yazi_core::mgr::Yanked; use yazi_macro::{act, render}; use yazi_parser::mgr::YankOpt; -use yazi_shared::event::Data; +use yazi_shared::{event::Data, url::CovUrl}; use crate::{Actor, Ctx}; @@ -16,7 +16,8 @@ impl Actor for Yank { fn act(cx: &mut Ctx, opt: Self::Options) -> Result { act!(mgr:escape_visual, cx)?; - cx.mgr.yanked = Yanked::new(opt.cut, cx.tab().selected_or_hovered().cloned().collect()); + cx.mgr.yanked = + Yanked::new(opt.cut, cx.tab().selected_or_hovered().cloned().map(CovUrl).collect()); render!(cx.mgr.yanked.catchup_revision(true)); act!(mgr:escape_select, cx) diff --git a/yazi-binding/src/url.rs b/yazi-binding/src/url.rs index 91261abb..95a82ad6 100644 --- a/yazi-binding/src/url.rs +++ b/yazi-binding/src/url.rs @@ -1,7 +1,7 @@ use std::{borrow::Cow, ops::Deref}; use mlua::{AnyUserData, ExternalError, FromLua, Lua, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataRef, Value}; -use yazi_shared::url::Scheme; +use yazi_shared::url::{CovUrl, Scheme}; use crate::{Urn, cached_field}; @@ -41,6 +41,10 @@ impl<'a> From<&'a Url> for Cow<'a, yazi_shared::url::Url> { fn from(value: &'a Url) -> Self { Cow::Borrowed(&value.inner) } } +impl From for yazi_shared::url::CovUrl { + fn from(value: Url) -> Self { CovUrl(value.inner) } +} + impl TryFrom<&[u8]> for Url { type Error = mlua::Error; @@ -159,10 +163,10 @@ impl UserData for Url { methods.add_meta_method(MetaMethod::Eq, |_, me, other: UrlRef| Ok(me.inner == other.inner)); methods.add_meta_method(MetaMethod::ToString, |lua, me, ()| { - lua.create_string(me.as_os_str().as_encoded_bytes()) + lua.create_string(me.os_str().as_encoded_bytes()) }); methods.add_meta_method(MetaMethod::Concat, |lua, lhs, rhs: mlua::String| { - lua.create_string([lhs.as_os_str().as_encoded_bytes(), &rhs.as_bytes()].concat()) + lua.create_string([lhs.os_str().as_encoded_bytes(), &rhs.as_bytes()].concat()) }); } } diff --git a/yazi-core/src/mgr/yanked.rs b/yazi-core/src/mgr/yanked.rs index e585ceff..e585419b 100644 --- a/yazi-core/src/mgr/yanked.rs +++ b/yazi-core/src/mgr/yanked.rs @@ -3,28 +3,28 @@ use std::{collections::HashSet, ops::Deref}; use yazi_dds::Pubsub; use yazi_fs::FilesOp; use yazi_macro::err; -use yazi_shared::url::Url; +use yazi_shared::url::{CovUrl, Url}; #[derive(Debug, Default)] pub struct Yanked { pub cut: bool, - urls: HashSet, + urls: HashSet, version: u64, revision: u64, } impl Deref for Yanked { - type Target = HashSet; + type Target = HashSet; fn deref(&self) -> &Self::Target { &self.urls } } impl Yanked { - pub fn new(cut: bool, urls: HashSet) -> Self { Self { cut, urls, ..Default::default() } } + pub fn new(cut: bool, urls: HashSet) -> Self { Self { cut, urls, ..Default::default() } } pub fn remove(&mut self, url: &Url) { - if self.urls.remove(url) { + if self.urls.remove(CovUrl::new(url)) { self.revision += 1; } } @@ -38,11 +38,15 @@ impl Yanked { self.revision += 1; } + #[inline] + pub fn contains(&self, url: impl AsRef) -> bool { self.urls.contains(CovUrl::new(&url)) } + pub fn contains_in(&self, dir: &Url) -> bool { self.urls.iter().any(|u| { let mut it = u.components(); - // FIXME - it.next_back().is_some() && it == dir.components() && u.parent_url().as_ref() == Some(dir) + it.next_back().is_some() + && it.covariant(&dir.components()) + && u.parent_url().is_some_and(|p| p == *dir) }) } @@ -56,7 +60,7 @@ impl Yanked { if !addition.is_empty() { let old = self.urls.len(); - self.urls.extend(addition); + self.urls.extend(addition.into_iter().map(CovUrl)); self.revision += (old != self.urls.len()) as u64; } } diff --git a/yazi-core/src/tab/selected.rs b/yazi-core/src/tab/selected.rs index 769e626f..3a0dc99f 100644 --- a/yazi-core/src/tab/selected.rs +++ b/yazi-core/src/tab/selected.rs @@ -2,21 +2,29 @@ use std::{collections::HashMap, ops::Deref}; use indexmap::IndexMap; use yazi_fs::FilesOp; -use yazi_shared::{timestamp_us, url::Url}; +use yazi_shared::{timestamp_us, url::{CovUrl, Url}}; #[derive(Default)] pub struct Selected { - inner: IndexMap, - parents: HashMap, -} - -impl Deref for Selected { - type Target = IndexMap; - - fn deref(&self) -> &Self::Target { &self.inner } + inner: IndexMap, + parents: HashMap, } impl Selected { + #[inline] + pub fn len(&self) -> usize { self.inner.len() } + + #[inline] + pub fn is_empty(&self) -> bool { self.inner.is_empty() } + + #[inline] + pub fn values(&self) -> impl Iterator { self.inner.keys().map(Deref::deref) } + + #[inline] + pub fn contains(&self, url: impl AsRef) -> bool { + self.inner.contains_key(CovUrl::new(&url)) + } + #[inline] pub fn add(&mut self, url: &Url) -> bool { self.add_same(&[url]) == 1 } @@ -33,7 +41,7 @@ impl Selected { fn add_same(&mut self, urls: &[impl AsRef]) -> usize { // If it has appeared as a parent let urls: Vec<_> = - urls.iter().map(|u| u.as_ref()).filter(|&u| !self.parents.contains_key(u)).collect(); + urls.iter().map(CovUrl::new).filter(|&u| !self.parents.contains_key(u)).collect(); if urls.is_empty() { return 0; } @@ -79,12 +87,12 @@ impl Selected { } fn remove_same(&mut self, urls: &[impl AsRef]) -> usize { - let count = urls.iter().filter_map(|u| self.inner.swap_remove(u.as_ref())).count(); + let count = urls.iter().filter_map(|u| self.inner.swap_remove(CovUrl::new(u))).count(); if count == 0 { return 0; } - let mut parent = urls[0].as_ref().parent_url(); + let mut parent = CovUrl::new(&urls[0]).parent_url(); while let Some(u) = parent { let n = self.parents.get_mut(&u).unwrap(); @@ -104,7 +112,7 @@ impl Selected { } pub fn apply_op(&mut self, op: &FilesOp) { - let (removal, addition) = op.diff_recoverable(|u| self.contains_key(u)); + let (removal, addition) = op.diff_recoverable(|u| self.contains(u)); if !removal.is_empty() { self.remove_many(&removal); } diff --git a/yazi-core/src/tab/tab.rs b/yazi-core/src/tab/tab.rs index 63ea995b..9d4af76b 100644 --- a/yazi-core/src/tab/tab.rs +++ b/yazi-core/src/tab/tab.rs @@ -89,7 +89,7 @@ impl Tab { if self.selected.is_empty() { Box::new(self.hovered().map(|h| &h.url).into_iter()) } else { - Box::new(self.selected.keys()) + Box::new(self.selected.values()) } } @@ -98,7 +98,7 @@ impl Tab { if self.selected.is_empty() { Box::new([&h.url, &h.url].into_iter()) } else { - Box::new([&h.url].into_iter().chain(self.selected.keys())) + Box::new([&h.url].into_iter().chain(self.selected.values())) } } diff --git a/yazi-core/src/tasks/file.rs b/yazi-core/src/tasks/file.rs index 65bff641..27441aad 100644 --- a/yazi-core/src/tasks/file.rs +++ b/yazi-core/src/tasks/file.rs @@ -1,51 +1,51 @@ use std::collections::HashSet; use tracing::debug; -use yazi_shared::url::Url; +use yazi_shared::url::{CovUrl, Url}; use super::Tasks; impl Tasks { - pub fn file_cut(&self, src: &[&Url], dest: &Url, force: bool) { + pub fn file_cut(&self, src: &[&CovUrl], dest: &Url, force: bool) { for &u in src { let to = dest.join(u.file_name().unwrap()); if force && *u == to { debug!("file_cut: same file, skipping {:?}", to); } else { - self.scheduler.file_cut(u.clone(), to, force); + self.scheduler.file_cut(u.0.clone(), to, force); } } } - pub fn file_copy(&self, src: &[&Url], dest: &Url, force: bool, follow: bool) { + pub fn file_copy(&self, src: &[&CovUrl], dest: &Url, force: bool, follow: bool) { for &u in src { let to = dest.join(u.file_name().unwrap()); if force && *u == to { debug!("file_copy: same file, skipping {:?}", to); } else { - self.scheduler.file_copy(u.clone(), to, force, follow); + self.scheduler.file_copy(u.0.clone(), to, force, follow); } } } - pub fn file_link(&self, src: &HashSet, dest: &Url, relative: bool, force: bool) { + pub fn file_link(&self, src: &HashSet, dest: &Url, relative: bool, force: bool) { for u in src { let to = dest.join(u.file_name().unwrap()); if force && *u == to { debug!("file_link: same file, skipping {:?}", to); } else { - self.scheduler.file_link(u.clone(), to, relative, force); + self.scheduler.file_link(u.0.clone(), to, relative, force); } } } - pub fn file_hardlink(&self, src: &HashSet, dest: &Url, force: bool, follow: bool) { + pub fn file_hardlink(&self, src: &HashSet, dest: &Url, force: bool, follow: bool) { for u in src { let to = dest.join(u.file_name().unwrap()); if force && *u == to { debug!("file_hardlink: same file, skipping {:?}", to); } else { - self.scheduler.file_hardlink(u.clone(), to, force, follow); + self.scheduler.file_hardlink(u.0.clone(), to, force, follow); } } } diff --git a/yazi-dds/src/body/yank.rs b/yazi-dds/src/body/yank.rs index 3f1f443e..245a394e 100644 --- a/yazi-dds/src/body/yank.rs +++ b/yazi-dds/src/body/yank.rs @@ -3,7 +3,7 @@ use std::{borrow::Cow, collections::HashSet}; use mlua::{IntoLua, Lua, Value}; use serde::{Deserialize, Serialize}; use yazi_parser::mgr::UpdateYankedOpt; -use yazi_shared::url::Url; +use yazi_shared::url::CovUrl; use super::Body; @@ -11,13 +11,13 @@ use super::Body; pub struct BodyYank<'a>(UpdateYankedOpt<'a>); impl<'a> BodyYank<'a> { - pub fn borrowed(cut: bool, urls: &'a HashSet) -> Body<'a> { + pub fn borrowed(cut: bool, urls: &'a HashSet) -> Body<'a> { Self(UpdateYankedOpt { cut, urls: Cow::Borrowed(urls) }).into() } } impl BodyYank<'static> { - pub fn owned(cut: bool, _: &HashSet) -> Body<'static> { + pub fn owned(cut: bool, _: &HashSet) -> Body<'static> { Self(UpdateYankedOpt { cut, urls: Default::default() }).into() } } diff --git a/yazi-dds/src/pubsub.rs b/yazi-dds/src/pubsub.rs index e2db0362..a9f3795d 100644 --- a/yazi-dds/src/pubsub.rs +++ b/yazi-dds/src/pubsub.rs @@ -5,7 +5,7 @@ use mlua::Function; use parking_lot::RwLock; use yazi_boot::BOOT; use yazi_fs::FolderStage; -use yazi_shared::{Id, RoCell, url::Url}; +use yazi_shared::{Id, RoCell, url::{CovUrl, Url}}; use crate::{Client, ID, PEERS, body::{Body, BodyBulk, BodyHi, BodyMoveItem}}; @@ -157,7 +157,7 @@ impl Pubsub { pub_after!(rename(tab: Id, from: &Url, to: &Url), (tab, from, to)); - pub_after!(@yank(cut: bool, urls: &HashSet), (cut, urls)); + pub_after!(@yank(cut: bool, urls: &HashSet), (cut, urls)); pub_after!(move(items: Vec), (&items), (items)); diff --git a/yazi-parser/src/mgr/update_yanked.rs b/yazi-parser/src/mgr/update_yanked.rs index d1f60874..0d303ce5 100644 --- a/yazi-parser/src/mgr/update_yanked.rs +++ b/yazi-parser/src/mgr/update_yanked.rs @@ -4,17 +4,17 @@ use anyhow::bail; use mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, MultiValue, ObjectLike, UserData, UserDataFields, UserDataMethods, Value}; use serde::{Deserialize, Serialize}; use yazi_binding::get_metatable; -use yazi_shared::{event::CmdCow, url::Url}; +use yazi_shared::{event::CmdCow, url::CovUrl}; type Iter = yazi_binding::Iter< - std::iter::Map, fn(Url) -> yazi_binding::Url>, + std::iter::Map, fn(CovUrl) -> yazi_binding::Url>, yazi_binding::Url, >; #[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct UpdateYankedOpt<'a> { pub cut: bool, - pub urls: Cow<'a, HashSet>, + pub urls: Cow<'a, HashSet>, } impl TryFrom for UpdateYankedOpt<'_> { diff --git a/yazi-shared/src/url/component.rs b/yazi-shared/src/url/component.rs index 164361af..dc5d10f5 100644 --- a/yazi-shared/src/url/component.rs +++ b/yazi-shared/src/url/component.rs @@ -74,13 +74,24 @@ impl<'a> Components<'a> { } pub fn os_str(&self) -> Cow<'a, OsStr> { + let path = self.inner.as_path(); if !self.scheme.is_virtual() || self.scheme_yielded { - return Cow::Borrowed(self.inner.as_path().as_os_str()); + return path.as_os_str().into(); } - let mut oss = OsString::from(format!("{}", self.scheme)); - oss.push(self.inner.as_path()); - Cow::Owned(oss) + let mut s = OsString::from(format!("{}", self.scheme)); + s.reserve_exact(path.as_os_str().len()); + s.push(path); + s.into() + } + + pub fn covariant(&self, other: &Self) -> bool { + match (self.scheme_yielded, other.scheme_yielded) { + (false, false) => {} + (true, true) if self.scheme.covariant(other.scheme) => {} + _ => return false, + } + self.inner == other.inner } } diff --git a/yazi-shared/src/url/cov.rs b/yazi-shared/src/url/cov.rs new file mode 100644 index 00000000..2f33f0a3 --- /dev/null +++ b/yazi-shared/src/url/cov.rs @@ -0,0 +1,54 @@ +use std::{hash::{Hash, Hasher}, ops::Deref}; + +use serde::{Deserialize, Serialize}; + +use crate::url::Url; + +#[derive(Clone, Debug, Deserialize, Eq, Serialize)] +#[repr(transparent)] +pub struct CovUrl(pub Url); + +impl Deref for CovUrl { + type Target = Url; + + fn deref(&self) -> &Self::Target { &self.0 } +} + +impl AsRef for CovUrl { + fn as_ref(&self) -> &Url { &self.0 } +} + +impl From for CovUrl { + fn from(value: Url) -> Self { Self(value) } +} + +impl From for Url { + fn from(value: CovUrl) -> Self { value.0 } +} + +impl Hash for CovUrl { + fn hash(&self, state: &mut H) { + self.loc.hash(state); + if self.scheme.is_virtual() { + self.scheme.hash(state); + } + } +} + +impl PartialEq for CovUrl { + fn eq(&self, other: &Self) -> bool { self.covariant(other) } +} + +impl PartialEq for CovUrl { + fn eq(&self, other: &Url) -> bool { self.covariant(other) } +} + +impl CovUrl { + #[inline] + pub fn new>(u: &T) -> &Self { + unsafe { &*(u.as_ref() as *const Url as *const Self) } + } + + #[inline] + pub fn parent_url(&self) -> Option { self.0.parent_url().map(CovUrl) } +} diff --git a/yazi-shared/src/url/loc.rs b/yazi-shared/src/url/loc.rs index 17db445b..7c48d651 100644 --- a/yazi-shared/src/url/loc.rs +++ b/yazi-shared/src/url/loc.rs @@ -15,6 +15,10 @@ impl Deref for Loc { fn deref(&self) -> &Self::Target { &self.inner } } +impl AsRef for Loc { + fn as_ref(&self) -> &Path { &self.inner } +} + impl PartialEq for Loc { fn eq(&self, other: &Self) -> bool { self.inner == other.inner } } diff --git a/yazi-shared/src/url/mod.rs b/yazi-shared/src/url/mod.rs index b9aa25b3..08f48576 100644 --- a/yazi-shared/src/url/mod.rs +++ b/yazi-shared/src/url/mod.rs @@ -1 +1 @@ -yazi_macro::mod_flat!(component display loc scheme url urn); +yazi_macro::mod_flat!(component cov display loc scheme url urn); diff --git a/yazi-shared/src/url/scheme.rs b/yazi-shared/src/url/scheme.rs index 3034fa4c..948f05a7 100644 --- a/yazi-shared/src/url/scheme.rs +++ b/yazi-shared/src/url/scheme.rs @@ -47,17 +47,9 @@ impl Scheme { }) } + #[inline] pub fn covariant(&self, other: &Self) -> bool { - match (self, other) { - // Local files - ( - Self::Regular | Self::Search(_) | Self::SearchItem, - Self::Regular | Self::Search(_) | Self::SearchItem, - ) => true, - - // Virtual files within the same namespace - (a, b) => a == b, - } + if self.is_virtual() || other.is_virtual() { self == other } else { true } } #[inline] diff --git a/yazi-shared/src/url/url.rs b/yazi-shared/src/url/url.rs index 7217d9ac..1540624f 100644 --- a/yazi-shared/src/url/url.rs +++ b/yazi-shared/src/url/url.rs @@ -1,4 +1,4 @@ -use std::{borrow::Cow, ffi::OsStr, fmt::{Debug, Formatter}, hash::{BuildHasher, Hash, Hasher}, ops::Deref, path::{Path, PathBuf}}; +use std::{borrow::Cow, ffi::OsStr, fmt::{Debug, Formatter}, hash::BuildHasher, ops::Deref, path::{Path, PathBuf}}; use percent_encoding::percent_decode; use serde::{Deserialize, Serialize}; @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use super::UrnBuf; use crate::{IntoOsStr, url::{Components, Display, Loc, Scheme}}; -#[derive(Clone, Default, Eq, Ord, PartialOrd)] +#[derive(Clone, Default, Eq, Ord, PartialOrd, PartialEq, Hash)] pub struct Url { pub loc: Loc, pub scheme: Scheme, @@ -18,19 +18,6 @@ impl Deref for Url { fn deref(&self) -> &Self::Target { &self.loc } } -impl Debug for Url { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let Self { scheme, loc } = self; - match scheme { - Scheme::Regular => write!(f, "{scheme}{}", loc.display()), - Scheme::Search(_) => write!(f, "{scheme}{}", loc.display()), - Scheme::SearchItem => write!(f, "{scheme}{}", loc.display()), - Scheme::Archive(_) => write!(f, "{scheme}{}", loc.display()), - Scheme::Sftp(_) => write!(f, "{scheme}{}", loc.display()), - } - } -} - impl From for Url { fn from(loc: Loc) -> Self { Self { loc, scheme: Scheme::Regular } } } @@ -165,7 +152,7 @@ impl Url { } Some(Self { - loc: self.loc.strip_prefix(base.loc.as_path()).ok()?.into(), + loc: self.loc.strip_prefix(&base.loc).ok()?.into(), scheme: self.scheme.clone(), }) } @@ -229,36 +216,9 @@ impl Url { pub fn into_path(self) -> PathBuf { self.loc.into_path() } } -impl Hash for Url { - fn hash(&self, state: &mut H) { - self.loc.hash(state); - - match &self.scheme { - Scheme::Regular => {} - Scheme::Search(_) => { - self.scheme.hash(state); - } - Scheme::SearchItem => {} - Scheme::Archive(_) => { - self.scheme.hash(state); - } - Scheme::Sftp(_) => { - self.scheme.hash(state); - } - } - } -} - -impl PartialEq for Url { - fn eq(&self, other: &Self) -> bool { - if self.loc != other.loc { - return false; - } - - match (&self.scheme, &other.scheme) { - (Scheme::Regular | Scheme::SearchItem, Scheme::Regular | Scheme::SearchItem) => true, - _ => self.scheme == other.scheme, - } +impl Debug for Url { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}{}", self.scheme, self.loc.display()) } }