From 97c63e2708fc83b5a8ca8be7939f9e4df364de55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20misaki=20masa?= Date: Wed, 5 Nov 2025 01:20:56 +0800 Subject: [PATCH] fix: make file counter more distinguishable in dark mode (#3311) --- Cargo.lock | 21 ++-- Cargo.toml | 8 +- yazi-actor/src/lives/mod.rs | 2 - yazi-binding/src/elements/mod.rs | 2 - yazi-boot/Cargo.toml | 2 +- yazi-boot/src/actions/mod.rs | 2 - yazi-cli/Cargo.toml | 2 +- yazi-cli/src/package/mod.rs | 2 - yazi-config/preset/theme-dark.toml | 2 +- yazi-config/src/lib.rs | 2 - yazi-core/src/lib.rs | 1 - yazi-dds/src/ember/mod.rs | 2 - yazi-fm/src/main.rs | 2 +- yazi-fs/src/path/clean.rs | 3 +- yazi-fs/src/path/expand.rs | 8 +- yazi-fs/src/path/relative.rs | 4 +- yazi-plugin/src/bindings/mod.rs | 2 - yazi-plugin/src/fs/mod.rs | 2 - yazi-plugin/src/isolate/mod.rs | 2 - yazi-plugin/src/loader/mod.rs | 2 - yazi-plugin/src/process/mod.rs | 2 - yazi-plugin/src/pubsub/mod.rs | 2 - yazi-plugin/src/utils/mod.rs | 2 - yazi-scheduler/src/file/mod.rs | 2 - yazi-scheduler/src/plugin/mod.rs | 2 - yazi-scheduler/src/prework/mod.rs | 2 - yazi-scheduler/src/process/mod.rs | 2 - yazi-shared/src/event/mod.rs | 2 - yazi-shared/src/loc/buf.rs | 72 ++++++----- yazi-shared/src/loc/loc.rs | 168 ++++++++++++-------------- yazi-shared/src/path/buf.rs | 45 +++++++ yazi-shared/src/path/component.rs | 0 yazi-shared/src/path/components.rs | 0 yazi-shared/src/path/dyn.rs | 9 ++ yazi-shared/src/path/inner.rs | 13 ++ yazi-shared/src/path/mod.rs | 2 +- yazi-shared/src/path/path.rs | 81 +++++++++++++ yazi-shared/src/path/traits.rs | 185 ++++++++++------------------- yazi-shared/src/url/buf.rs | 6 +- yazi-shared/src/url/cow.rs | 6 +- yazi-shared/src/url/traits.rs | 4 +- yazi-shared/src/url/url.rs | 20 ++-- 42 files changed, 378 insertions(+), 322 deletions(-) create mode 100644 yazi-shared/src/path/buf.rs create mode 100644 yazi-shared/src/path/component.rs create mode 100644 yazi-shared/src/path/components.rs create mode 100644 yazi-shared/src/path/dyn.rs create mode 100644 yazi-shared/src/path/inner.rs create mode 100644 yazi-shared/src/path/path.rs diff --git a/Cargo.lock b/Cargo.lock index 5420d1d3..ecd39549 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -459,9 +459,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.43" +version = "1.2.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2" +checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3" dependencies = [ "find-msvc-tools", "jobserver", @@ -568,9 +568,9 @@ dependencies = [ [[package]] name = "clap_complete_nushell" -version = "4.5.9" +version = "4.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "811159f339691baacdf7d534df2946b9d217014081099e23d31d887d99521e70" +checksum = "685bc86fd34b7467e0532a4f8435ab107960d69a243785ef0275e571b35b641a" dependencies = [ "clap", "clap_complete", @@ -2233,11 +2233,10 @@ dependencies = [ [[package]] name = "num-bigint-dig" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +checksum = "82c79c15c05d4bf82b6f5ef163104cc81a760d8e874d38ac50ab67c8877b647b" dependencies = [ - "byteorder", "lazy_static", "libm", "num-integer", @@ -3774,9 +3773,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.16" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" dependencies = [ "bytes", "futures-core", @@ -4112,9 +4111,9 @@ dependencies = [ [[package]] name = "version-compare" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" [[package]] name = "version_check" diff --git a/Cargo.toml b/Cargo.toml index 7033a0ad..55fb0ce3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,9 +50,15 @@ serde_json = "1.0.145" syntect = { version = "5.3.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] } tokio = { version = "1.48.0", features = [ "full" ] } tokio-stream = "0.1.17" -tokio-util = "0.7.16" +tokio-util = "0.7.17" toml = { version = "0.9.8" } tracing = { version = "0.1.41", features = [ "max_level_debug", "release_max_level_debug" ] } twox-hash = { version = "2.1.2", default-features = false, features = [ "std", "random", "xxhash3_128" ] } unicode-width = { version = "0.2.0", default-features = false } uzers = "0.12.1" + +[workspace.lints.clippy] +format_push_string = "warn" +implicit_clone = "warn" +module_inception = "allow" +use_self = "warn" diff --git a/yazi-actor/src/lives/mod.rs b/yazi-actor/src/lives/mod.rs index 50f66a95..843fa013 100644 --- a/yazi-actor/src/lives/mod.rs +++ b/yazi-actor/src/lives/mod.rs @@ -1,3 +1 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!(core file files filter finder folder lives mode preference preview ptr selected tab tabs task tasks yanked); diff --git a/yazi-binding/src/elements/mod.rs b/yazi-binding/src/elements/mod.rs index 92e9e139..6cdcbd9c 100644 --- a/yazi-binding/src/elements/mod.rs +++ b/yazi-binding/src/elements/mod.rs @@ -1,3 +1 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!(align area bar border cell clear constraint edge elements gauge layout line list pad pos rect renderable row span table text wrap); diff --git a/yazi-boot/Cargo.toml b/yazi-boot/Cargo.toml index ca4b78ed..6670c893 100644 --- a/yazi-boot/Cargo.toml +++ b/yazi-boot/Cargo.toml @@ -30,5 +30,5 @@ yazi-shared = { path = "../yazi-shared", version = "25.9.15" } clap = { workspace = true } clap_complete = "4.5.60" clap_complete_fig = "4.5.2" -clap_complete_nushell = "4.5.9" +clap_complete_nushell = "4.5.10" vergen-gitcl = { version = "1.0.8", features = [ "build", "rustc" ] } diff --git a/yazi-boot/src/actions/mod.rs b/yazi-boot/src/actions/mod.rs index 4f7b0221..651f0ab6 100644 --- a/yazi-boot/src/actions/mod.rs +++ b/yazi-boot/src/actions/mod.rs @@ -1,3 +1 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!(actions clear_cache debug rustc triple version); diff --git a/yazi-cli/Cargo.toml b/yazi-cli/Cargo.toml index bf40c872..2fdbe660 100644 --- a/yazi-cli/Cargo.toml +++ b/yazi-cli/Cargo.toml @@ -43,7 +43,7 @@ anyhow = { workspace = true } clap = { workspace = true } clap_complete = "4.5.60" clap_complete_fig = "4.5.2" -clap_complete_nushell = "4.5.9" +clap_complete_nushell = "4.5.10" serde_json = { workspace = true } vergen-gitcl = { version = "1.0.8", features = [ "build" ] } diff --git a/yazi-cli/src/package/mod.rs b/yazi-cli/src/package/mod.rs index 7dde8fb2..e07284f0 100644 --- a/yazi-cli/src/package/mod.rs +++ b/yazi-cli/src/package/mod.rs @@ -1,5 +1,3 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!(add delete dependency deploy git hash install package upgrade); use anyhow::Context; diff --git a/yazi-config/preset/theme-dark.toml b/yazi-config/preset/theme-dark.toml index 7e1c3636..1fcf2dc7 100644 --- a/yazi-config/preset/theme-dark.toml +++ b/yazi-config/preset/theme-dark.toml @@ -41,7 +41,7 @@ marker_selected = { fg = "lightyellow", bg = "lightyellow" } # Count count_copied = { fg = "white", bg = "green" } count_cut = { fg = "white", bg = "red" } -count_selected = { fg = "white", bg = "yellow" } +count_selected = { fg = "black", bg = "yellow" } # Border border_symbol = "│" diff --git a/yazi-config/src/lib.rs b/yazi-config/src/lib.rs index 627de4df..11c4e37f 100644 --- a/yazi-config/src/lib.rs +++ b/yazi-config/src/lib.rs @@ -1,5 +1,3 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_pub!(keymap mgr open opener plugin popup preview tasks theme which vfs); yazi_macro::mod_flat!(color icon layout pattern platform preset priority style yazi); diff --git a/yazi-core/src/lib.rs b/yazi-core/src/lib.rs index 77af3b42..a9b8257a 100644 --- a/yazi-core/src/lib.rs +++ b/yazi-core/src/lib.rs @@ -1,7 +1,6 @@ #![allow( clippy::if_same_then_else, clippy::len_without_is_empty, - clippy::module_inception, clippy::option_map_unit_fn, clippy::unit_arg )] diff --git a/yazi-dds/src/ember/mod.rs b/yazi-dds/src/ember/mod.rs index d2edd226..cf313417 100644 --- a/yazi-dds/src/ember/mod.rs +++ b/yazi-dds/src/ember/mod.rs @@ -1,5 +1,3 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!( bulk bye cd custom delete ember hey hi hover load mount r#move rename tab trash yank ); diff --git a/yazi-fm/src/main.rs b/yazi-fm/src/main.rs index 1d43bf6c..64ae41e5 100644 --- a/yazi-fm/src/main.rs +++ b/yazi-fm/src/main.rs @@ -1,4 +1,4 @@ -#![allow(clippy::if_same_then_else, clippy::module_inception, clippy::unit_arg)] +#![allow(clippy::if_same_then_else, clippy::unit_arg)] #[cfg(all(not(target_os = "macos"), not(target_os = "windows")))] #[global_allocator] diff --git a/yazi-fs/src/path/clean.rs b/yazi-fs/src/path/clean.rs index c4dd7021..495a5388 100644 --- a/yazi-fs/src/path/clean.rs +++ b/yazi-fs/src/path/clean.rs @@ -10,7 +10,8 @@ pub fn clean_url<'a>(url: impl Into>) -> UrlBuf { cow.loc().trail().components().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"); UrlBuf { loc, scheme: cow.into_scheme().into() } } diff --git a/yazi-fs/src/path/expand.rs b/yazi-fs/src/path/expand.rs index 95fa8f26..eb0fedfe 100644 --- a/yazi-fs/src/path/expand.rs +++ b/yazi-fs/src/path/expand.rs @@ -22,7 +22,7 @@ fn expand_url_impl<'a>(url: Url<'a>) -> UrlCow<'a> { let uri_count = url.uri().components().count() as isize; let urn_count = url.urn().components().count() as isize; - let loc = LocBuf::with( + let loc = LocBuf::::with( PathBuf::from_iter([n_base, n_rest, n_urn]), (uri_count + rest_diff + urn_diff) as usize, (urn_count + urn_diff) as usize, @@ -69,7 +69,7 @@ pub fn absolute_url<'a>(url: Url<'a>) -> UrlCow<'a> { let b = url.loc.as_os_str().as_encoded_bytes(); if cfg!(windows) && b.len() == 2 && b[1] == b':' && b[0].is_ascii_alphabetic() { - let loc = LocBuf::with( + let loc = LocBuf::::with( format!(r"{}:\", b[0].to_ascii_uppercase() as char).into(), if url.has_base() { 0 } else { 2 }, if url.has_trail() { 0 } else { 2 }, @@ -81,7 +81,7 @@ pub fn absolute_url<'a>(url: Url<'a>) -> UrlCow<'a> { && home.is_absolute() { let add = home.components().count() - 1; // Home root ("~") has offset by the absolute root ("/") - let loc = LocBuf::with( + let loc = LocBuf::::with( home.join(rest), url.uri().components().count() + if url.has_base() { 0 } else { add }, url.urn().components().count() + if url.has_trail() { 0 } else { add }, @@ -90,7 +90,7 @@ pub fn absolute_url<'a>(url: Url<'a>) -> UrlCow<'a> { UrlBuf { loc, scheme: url.scheme.into() }.into() } else if !url.is_absolute() { let cwd = CWD.path(); - let loc = LocBuf::with( + let loc = LocBuf::::with( cwd.join(url.loc), url.uri().components().count(), url.urn().components().count(), diff --git a/yazi-fs/src/path/relative.rs b/yazi-fs/src/path/relative.rs index d7dc51fd..d584e908 100644 --- a/yazi-fs/src/path/relative.rs +++ b/yazi-fs/src/path/relative.rs @@ -25,7 +25,7 @@ pub(super) fn url_relative_to<'a>(from: UrlCow<'_>, to: UrlCow<'a>) -> Result::zeroed("."), scheme: to.scheme().into() }.into()); } let (mut f_it, mut t_it) = (from.components(), to.components()); @@ -47,5 +47,5 @@ pub(super) fn url_relative_to<'a>(from: UrlCow<'_>, to: UrlCow<'a>) -> Result::zeroed(buf), scheme: to.scheme().into() }.into()) } diff --git a/yazi-plugin/src/bindings/mod.rs b/yazi-plugin/src/bindings/mod.rs index 6c802be4..94e3eb6d 100644 --- a/yazi-plugin/src/bindings/mod.rs +++ b/yazi-plugin/src/bindings/mod.rs @@ -1,3 +1 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!(calculator chan image input layer mouse range); diff --git a/yazi-plugin/src/fs/mod.rs b/yazi-plugin/src/fs/mod.rs index 5d5a2756..c6ecf3bb 100644 --- a/yazi-plugin/src/fs/mod.rs +++ b/yazi-plugin/src/fs/mod.rs @@ -1,3 +1 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!(fs op); diff --git a/yazi-plugin/src/isolate/mod.rs b/yazi-plugin/src/isolate/mod.rs index 3fb51d26..a2b2e71a 100644 --- a/yazi-plugin/src/isolate/mod.rs +++ b/yazi-plugin/src/isolate/mod.rs @@ -1,3 +1 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!(entry fetch isolate peek preload seek spot); diff --git a/yazi-plugin/src/loader/mod.rs b/yazi-plugin/src/loader/mod.rs index 0aa7a9ae..a01533f9 100644 --- a/yazi-plugin/src/loader/mod.rs +++ b/yazi-plugin/src/loader/mod.rs @@ -1,5 +1,3 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!(chunk loader require); pub(super) fn init() { LOADER.with(<_>::default); } diff --git a/yazi-plugin/src/process/mod.rs b/yazi-plugin/src/process/mod.rs index d2a48a7b..cde165c8 100644 --- a/yazi-plugin/src/process/mod.rs +++ b/yazi-plugin/src/process/mod.rs @@ -1,3 +1 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!(child command output process status); diff --git a/yazi-plugin/src/pubsub/mod.rs b/yazi-plugin/src/pubsub/mod.rs index b020d7e4..d5fc7257 100644 --- a/yazi-plugin/src/pubsub/mod.rs +++ b/yazi-plugin/src/pubsub/mod.rs @@ -1,5 +1,3 @@ -#![allow(clippy::module_inception)] - use mlua::{IntoLua, Lua, Value}; use yazi_binding::{Composer, ComposerGet, ComposerSet}; diff --git a/yazi-plugin/src/utils/mod.rs b/yazi-plugin/src/utils/mod.rs index c1f3a585..13c186d8 100644 --- a/yazi-plugin/src/utils/mod.rs +++ b/yazi-plugin/src/utils/mod.rs @@ -1,5 +1,3 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!( app cache call image json layer log preview process spot sync target text time user utils ); diff --git a/yazi-scheduler/src/file/mod.rs b/yazi-scheduler/src/file/mod.rs index 507b4bff..9ae8d171 100644 --- a/yazi-scheduler/src/file/mod.rs +++ b/yazi-scheduler/src/file/mod.rs @@ -1,3 +1 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!(file out progress r#in); diff --git a/yazi-scheduler/src/plugin/mod.rs b/yazi-scheduler/src/plugin/mod.rs index c38c18f2..b63ee8ce 100644 --- a/yazi-scheduler/src/plugin/mod.rs +++ b/yazi-scheduler/src/plugin/mod.rs @@ -1,3 +1 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!(out plugin progress r#in); diff --git a/yazi-scheduler/src/prework/mod.rs b/yazi-scheduler/src/prework/mod.rs index c3bf4602..101e7d60 100644 --- a/yazi-scheduler/src/prework/mod.rs +++ b/yazi-scheduler/src/prework/mod.rs @@ -1,3 +1 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!(out prework progress r#in); diff --git a/yazi-scheduler/src/process/mod.rs b/yazi-scheduler/src/process/mod.rs index eb48eb57..13a6c8ee 100644 --- a/yazi-scheduler/src/process/mod.rs +++ b/yazi-scheduler/src/process/mod.rs @@ -1,3 +1 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!(out process progress r#in shell); diff --git a/yazi-shared/src/event/mod.rs b/yazi-shared/src/event/mod.rs index febfd0a4..d6fc14a1 100644 --- a/yazi-shared/src/event/mod.rs +++ b/yazi-shared/src/event/mod.rs @@ -1,5 +1,3 @@ -#![allow(clippy::module_inception)] - yazi_macro::mod_flat!(cmd cow event); pub static NEED_RENDER: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false); diff --git a/yazi-shared/src/loc/buf.rs b/yazi-shared/src/loc/buf.rs index b2c6bd72..869adcc5 100644 --- a/yazi-shared/src/loc/buf.rs +++ b/yazi-shared/src/loc/buf.rs @@ -1,8 +1,8 @@ -use std::{cmp, ffi::OsStr, fmt::{self, Debug, Formatter}, hash::{Hash, Hasher}, ops::Deref, path::PathBuf}; +use std::{cmp, ffi::OsStr, fmt::{self, Debug, Formatter}, hash::{Hash, Hasher}, marker::PhantomData, ops::Deref, path::PathBuf}; use anyhow::Result; -use crate::{loc::Loc, path::{PathBufLike, PathLike}}; +use crate::{loc::Loc, path::{AsInnerView, AsPathView, PathBufLike, PathLike}}; #[derive(Clone, Default, Eq)] pub struct LocBuf { @@ -20,11 +20,9 @@ where fn deref(&self) -> &Self::Target { &self.inner } } -impl

AsRef for LocBuf

-where - P: PathBufLike, -{ - fn as_ref(&self) -> &P::Borrowed { self.inner.as_ref() } +// FIXME: remove +impl AsRef for LocBuf { + fn as_ref(&self) -> &std::path::Path { self.inner.as_ref() } } impl

PartialEq for LocBuf

@@ -54,7 +52,7 @@ where impl

Hash for LocBuf

where P: PathBufLike, - P::Borrowed: Hash, + for<'a> &'a P: AsPathView<'a, P::Borrowed<'a>>, { fn hash(&self, state: &mut H) { self.as_loc().hash(state) } } @@ -62,7 +60,7 @@ where impl

Debug for LocBuf

where P: PathBufLike + Debug, - P::Borrowed: Debug, + for<'a> &'a P: AsPathView<'a, P::Borrowed<'a>>, { fn fmt(&self, f: &mut Formatter) -> fmt::Result { f.debug_struct("LocBuf") @@ -76,9 +74,10 @@ where impl

From

for LocBuf

where P: PathBufLike, + for<'a> &'a P: AsPathView<'a, P::Borrowed<'a>>, { fn from(path: P) -> Self { - let Loc { inner, uri, urn } = Loc::from(&path); + let Loc { inner, uri, urn, _phantom } = Loc::bare(&path); let len = inner.len(); let mut bytes = path.into_encoded_bytes(); @@ -94,13 +93,14 @@ impl> From<&T> for LocBuf { impl

LocBuf

where P: PathBufLike, + for<'a> &'a P: AsPathView<'a, P::Borrowed<'a>>, { - pub fn new(path: P, base: &T, trail: &T) -> Self + pub fn new<'a, T>(path: P, base: T, trail: T) -> Self where - T: AsRef + ?Sized, + T: for<'b> AsPathView<'a, as PathLike<'b>>::View<'a>>, { let loc = Self::from(path); - let Loc { inner, uri, urn } = Loc::new(&loc.inner, base, trail); + let Loc { inner, uri, urn, _phantom } = Loc::new(&loc.inner, base, trail); debug_assert!(inner.encoded_bytes() == loc.inner.encoded_bytes()); Self { inner: loc.inner, uri, urn } @@ -108,10 +108,10 @@ where pub fn with(path: P, uri: usize, urn: usize) -> Result where - P::Borrowed: PathLike, + for<'a> P::Borrowed<'a>: PathLike<'a>, { let loc = Self::from(path); - let Loc { inner, uri, urn } = Loc::with(&loc.inner, uri, urn)?; + let Loc { inner, uri, urn, _phantom } = Loc::with(&loc.inner, uri, urn)?; debug_assert!(inner.encoded_bytes() == loc.inner.encoded_bytes()); Ok(Self { inner: loc.inner, uri, urn }) @@ -126,27 +126,31 @@ where T: Into

, { let loc = Self::from(path.into()); - let Loc { inner, uri, urn } = Loc::zeroed(&loc.inner); + let Loc { inner, uri, urn, _phantom } = Loc::zeroed(&loc.inner); debug_assert!(inner.encoded_bytes() == loc.inner.encoded_bytes()); Self { inner: loc.inner, uri, urn } } - pub fn floated(path: T, base: &U) -> Self + pub fn floated<'a, T>(path: P, base: T) -> Self where - T: Into

, - U: AsRef + ?Sized, + T: for<'b> AsPathView<'a, as PathLike<'b>>::View<'a>>, { - let loc = Self::from(path.into()); - let Loc { inner, uri, urn } = Loc::floated(&loc.inner, base); + let loc = Self::from(path); + let Loc { inner, uri, urn, _phantom } = Loc::floated(&loc.inner, base); debug_assert!(inner.encoded_bytes() == loc.inner.encoded_bytes()); Self { inner: loc.inner, uri, urn } } #[inline] - pub fn as_loc<'a>(&'a self) -> Loc<'a, P::Borrowed> { - Loc { inner: self.inner.as_ref(), uri: self.uri, urn: self.urn } + pub fn as_loc<'a>(&'a self) -> Loc<'a, P::Borrowed<'a>> { + Loc { + inner: self.inner.as_path_view(), + uri: self.uri, + urn: self.urn, + _phantom: PhantomData, + } } #[inline] @@ -162,7 +166,7 @@ where pub fn set_name(&mut self, name: T) where - T: AsRef, + T: for<'a> AsInnerView<'a, P::InnerRef<'a>>, { let old = self.inner.len(); self.mutate(|path| path.set_file_name(name)); @@ -189,9 +193,10 @@ where } #[inline] - pub fn rebase(&self, base: &P::Borrowed) -> Self + pub fn rebase<'a, 'b>(&'a self, base: P::Borrowed<'b>) -> Self where - ::Owned: Into, + 'a: 'b, + for<'c> as PathLike<'c>>::Owned: Into, { let mut loc: Self = base.join(self.uri()).into(); (loc.uri, loc.urn) = (self.uri, self.urn); @@ -213,33 +218,34 @@ where impl

LocBuf

where P: PathBufLike, + for<'a> &'a P: AsPathView<'a, P::Borrowed<'a>>, { #[inline] - pub fn uri(&self) -> &P::Borrowed { self.as_loc().uri() } + pub fn uri(&self) -> P::Borrowed<'_> { self.as_loc().uri() } #[inline] - pub fn urn(&self) -> &P::Borrowed { self.as_loc().urn() } + pub fn urn(&self) -> P::Borrowed<'_> { self.as_loc().urn() } #[inline] - pub fn base(&self) -> &P::Borrowed { self.as_loc().base() } + pub fn base(&self) -> P::Borrowed<'_> { self.as_loc().base() } #[inline] pub fn has_base(&self) -> bool { self.as_loc().has_base() } #[inline] - pub fn trail(&self) -> &P::Borrowed { self.as_loc().trail() } + pub fn trail(&self) -> P::Borrowed<'_> { self.as_loc().trail() } #[inline] pub fn has_trail(&self) -> bool { self.as_loc().has_trail() } #[inline] - pub fn name(&self) -> Option<&::Inner> { self.as_loc().name() } + pub fn name(&self) -> Option< as PathLike<'_>>::Inner> { self.as_loc().name() } #[inline] - pub fn stem(&self) -> Option<&::Inner> { self.as_loc().stem() } + pub fn stem(&self) -> Option< as PathLike<'_>>::Inner> { self.as_loc().stem() } #[inline] - pub fn ext(&self) -> Option<&::Inner> { self.as_loc().ext() } + pub fn ext(&self) -> Option< as PathLike<'_>>::Inner> { self.as_loc().ext() } } #[cfg(test)] diff --git a/yazi-shared/src/loc/loc.rs b/yazi-shared/src/loc/loc.rs index 58f2e357..06138a9b 100644 --- a/yazi-shared/src/loc/loc.rs +++ b/yazi-shared/src/loc/loc.rs @@ -1,125 +1,90 @@ -use std::{hash::{Hash, Hasher}, ops::Deref, path::Path}; +use std::{hash::{Hash, Hasher}, marker::PhantomData, ops::Deref, path::Path}; use anyhow::{Result, bail}; -use crate::{loc::LocBuf, path::{PathInner, PathLike}}; +use crate::{loc::LocBuf, path::{AsPathView, PathBufLike, PathInner, PathLike, ToPathOwned}}; -#[derive(Debug)] -pub struct Loc<'a, P: ?Sized + PathLike = Path> { - pub(super) inner: &'a P, - pub(super) uri: usize, - pub(super) urn: usize, +#[derive(Clone, Copy, Debug)] +pub struct Loc<'p, P = &'p Path> { + pub(super) inner: P, + pub(super) uri: usize, + pub(super) urn: usize, + pub(super) _phantom: PhantomData<&'p ()>, } -impl<'a, P> Copy for Loc<'a, P> where P: ?Sized + PathLike {} - -impl<'a, P> Clone for Loc<'a, P> +impl<'p, P> Default for Loc<'p, P> where - P: ?Sized + PathLike, + P: PathLike<'p>, { - fn clone(&self) -> Self { *self } + fn default() -> Self { Self { inner: P::default(), uri: 0, urn: 0, _phantom: PhantomData } } } -impl

Default for Loc<'static, P> +impl<'p, P> Deref for Loc<'p, P> where - P: ?Sized + PathLike, -{ - fn default() -> Self { Self { inner: P::default(), uri: 0, urn: 0 } } -} - -impl

Deref for Loc<'_, P> -where - P: ?Sized + PathLike, + P: PathLike<'p>, { type Target = P; - fn deref(&self) -> &Self::Target { self.inner } + fn deref(&self) -> &Self::Target { &self.inner } } -impl

AsRef

for Loc<'_, P> -where - P: ?Sized + PathLike, -{ - fn as_ref(&self) -> &P { self.inner } +// FIXME: remove +impl AsRef for Loc<'_, &std::path::Path> { + fn as_ref(&self) -> &std::path::Path { self.inner } } // --- Hash -impl

Hash for Loc<'_, P> +impl<'p, P> Hash for Loc<'p, P> where - P: ?Sized + PathLike + Hash, + P: PathLike<'p> + Hash, { fn hash(&self, state: &mut H) { self.inner.hash(state) } } -impl<'a, P, T> From<&'a T> for Loc<'a, P> +impl<'p, P> From> for LocBuf<

>::Owned> where - P: ?Sized + PathLike, - T: ?Sized + AsRef

, + P: PathLike<'p> + ToPathOwned<

>::Owned>, +

>::Owned: PathBufLike, { - fn from(value: &'a T) -> Self { - let path = value.as_ref(); - let Some(name) = path.file_name() else { - let uri = path.len(); - return Self { inner: path, uri, urn: 0 }; - }; - - let name_len = name.len(); - let prefix_len = - unsafe { name.encoded_bytes().as_ptr().offset_from_unsigned(path.encoded_bytes().as_ptr()) }; - - let bytes = path.encoded_bytes(); - Self { - inner: unsafe { P::from_encoded_bytes(&bytes[..prefix_len + name_len]) }, - uri: name_len, - urn: name_len, - } - } -} - -impl

From> for LocBuf<

::Owned> -where - P: ?Sized + PathLike + ToOwned::Owned>, -{ - fn from(value: Loc<'_, P>) -> Self { - Self { inner: value.inner.to_owned(), uri: value.uri, urn: value.urn } + fn from(value: Loc<'p, P>) -> Self { + Self { inner: value.inner.to_path_owned(), uri: value.uri, urn: value.urn } } } // --- Eq -impl

PartialEq for Loc<'_, P> +impl<'p, P> PartialEq for Loc<'p, P> where - P: ?Sized + PathLike + PartialEq, + P: PathLike<'p> + PartialEq, { fn eq(&self, other: &Self) -> bool { self.inner == other.inner } } -impl

Eq for Loc<'_, P> where P: ?Sized + PathLike + Eq {} +impl<'p, P> Eq for Loc<'p, P> where P: PathLike<'p> + Eq {} -impl<'a, P> Loc<'a, P> +impl<'p, P> Loc<'p, P> where - P: ?Sized + PathLike, + P: PathLike<'p>, { - pub fn new(path: &'a T, base: &U, trail: &U) -> Self + pub fn new<'a, T, U>(path: T, base: U, trail: U) -> Self where - T: AsRef

+ ?Sized, - U: AsRef

+ ?Sized, + T: AsPathView<'p, P>, + U: AsPathView<'a, P::View<'a>>, { - let mut loc = Self::from(path); + let mut loc = Self::bare(path); loc.uri = loc.inner.strip_prefix(base).expect("Loc must start with the given base").len(); loc.urn = loc.inner.strip_prefix(trail).expect("Loc must start with the given trail").len(); loc } - pub fn with(path: &'a T, uri: usize, urn: usize) -> Result + pub fn with(path: T, uri: usize, urn: usize) -> Result where - T: ?Sized + AsRef

, -

::Components<'a>: AsRef

+ Clone + DoubleEndedIterator, + T: AsPathView<'p, P>, { if urn > uri { bail!("URN cannot be longer than URI"); } - let mut loc = Self::from(path); + let mut loc = Self::bare(path); if uri == 0 { (loc.uri, loc.urn) = (0, 0); return Ok(loc); @@ -143,21 +108,44 @@ where Ok(loc) } - pub fn zeroed(path: &'a T) -> Self + pub fn bare(path: T) -> Self where - T: AsRef

+ ?Sized, + T: AsPathView<'p, P>, { - let mut loc = Self::from(path); + let path = path.as_path_view(); + let Some(name) = path.file_name() else { + let uri = path.len(); + return Self { inner: path, uri, urn: 0, _phantom: PhantomData }; + }; + + let name_len = name.len(); + let prefix_len = + unsafe { name.encoded_bytes().as_ptr().offset_from_unsigned(path.encoded_bytes().as_ptr()) }; + + let bytes = path.encoded_bytes(); + Self { + inner: unsafe { P::from_encoded_bytes(&bytes[..prefix_len + name_len]) }, + uri: name_len, + urn: name_len, + _phantom: PhantomData, + } + } + + pub fn zeroed(path: T) -> Self + where + T: AsPathView<'p, P>, + { + let mut loc = Self::bare(path); (loc.uri, loc.urn) = (0, 0); loc } - pub fn floated(path: &'a T, base: &U) -> Self + pub fn floated<'a, T, U>(path: T, base: U) -> Self where - T: AsRef

+ ?Sized, - U: AsRef

+ ?Sized, + T: AsPathView<'p, P>, + U: AsPathView<'a, P::View<'a>>, { - let mut loc = Self::from(path); + let mut loc = Self::bare(path); loc.uri = loc.inner.strip_prefix(base).expect("Loc must start with the given base").len(); loc } @@ -166,24 +154,24 @@ where pub fn as_loc(self) -> Self { self } #[inline] - pub fn as_path(self) -> &'a P { self.inner } + pub fn as_path(self) -> P { self.inner } #[inline] - pub fn uri(self) -> &'a P { + pub fn uri(self) -> P { unsafe { P::from_encoded_bytes(self.inner.encoded_bytes().get_unchecked(self.inner.len() - self.uri..)) } } #[inline] - pub fn urn(self) -> &'a P { + pub fn urn(self) -> P { unsafe { P::from_encoded_bytes(self.inner.encoded_bytes().get_unchecked(self.inner.len() - self.urn..)) } } #[inline] - pub fn base(self) -> &'a P { + pub fn base(self) -> P { unsafe { P::from_encoded_bytes(self.inner.encoded_bytes().get_unchecked(..self.inner.len() - self.uri)) } @@ -193,7 +181,7 @@ where pub fn has_base(self) -> bool { self.inner.len() != self.uri } #[inline] - pub fn trail(self) -> &'a P { + pub fn trail(self) -> P { unsafe { P::from_encoded_bytes(self.inner.encoded_bytes().get_unchecked(..self.inner.len() - self.urn)) } @@ -203,19 +191,19 @@ where pub fn has_trail(self) -> bool { self.inner.len() != self.urn } #[inline] - pub fn name(self) -> Option<&'a P::Inner> { self.inner.file_name() } + pub fn name(self) -> Option { self.inner.file_name() } #[inline] - pub fn stem(self) -> Option<&'a P::Inner> { self.inner.file_stem() } + pub fn stem(self) -> Option { self.inner.file_stem() } #[inline] - pub fn ext(self) -> Option<&'a P::Inner> { self.inner.extension() } + pub fn ext(self) -> Option { self.inner.extension() } #[inline] - pub fn parent(self) -> Option<&'a P> { self.inner.parent() } + pub fn parent(self) -> Option

{ self.inner.parent() } #[inline] - pub fn triple(self) -> (&'a P, &'a P, &'a P) { + pub fn triple(self) -> (P, P, P) { let len = self.inner.len(); let base = ..len - self.uri; @@ -232,9 +220,9 @@ where } #[inline] - pub fn strip_prefix(self, base: T) -> Option<&'a P> + pub fn strip_prefix<'a, T>(self, base: T) -> Option

where - T: AsRef

, + T: AsPathView<'a, P::View<'a>>, { self.inner.strip_prefix(base) } diff --git a/yazi-shared/src/path/buf.rs b/yazi-shared/src/path/buf.rs new file mode 100644 index 00000000..093a6b33 --- /dev/null +++ b/yazi-shared/src/path/buf.rs @@ -0,0 +1,45 @@ +use std::{fmt::Debug, hash::Hash}; + +use crate::path::{AsInnerView, AsPathView, PathInner, PathLike}; + +pub trait PathBufLike +where + Self: Default + 'static, +{ + type Inner: for<'a> AsInnerView<'a, Self::InnerRef<'a>>; + type InnerRef<'a>: PathInner<'a>; + type Borrowed<'a>: PathLike<'a> + AsPathView<'a, Self::Borrowed<'a>> + Debug + Hash; + + fn encoded_bytes(&self) -> &[u8]; + + unsafe fn from_encoded_bytes(bytes: Vec) -> Self; + + fn into_encoded_bytes(self) -> Vec; + + fn len(&self) -> usize { self.encoded_bytes().len() } + + fn set_file_name(&mut self, name: T) + where + T: for<'a> AsInnerView<'a, Self::InnerRef<'a>>; +} + +impl PathBufLike for std::path::PathBuf { + type Borrowed<'a> = &'a std::path::Path; + type Inner = std::ffi::OsString; + type InnerRef<'a> = &'a std::ffi::OsStr; + + fn encoded_bytes(&self) -> &[u8] { self.as_os_str().as_encoded_bytes() } + + unsafe fn from_encoded_bytes(bytes: Vec) -> Self { + Self::from(unsafe { Self::Inner::from_encoded_bytes_unchecked(bytes) }) + } + + fn into_encoded_bytes(self) -> Vec { self.into_os_string().into_encoded_bytes() } + + fn set_file_name(&mut self, name: T) + where + T: for<'a> AsInnerView<'a, Self::InnerRef<'a>>, + { + self.set_file_name(name.as_inner_view()); + } +} diff --git a/yazi-shared/src/path/component.rs b/yazi-shared/src/path/component.rs new file mode 100644 index 00000000..e69de29b diff --git a/yazi-shared/src/path/components.rs b/yazi-shared/src/path/components.rs new file mode 100644 index 00000000..e69de29b diff --git a/yazi-shared/src/path/dyn.rs b/yazi-shared/src/path/dyn.rs new file mode 100644 index 00000000..20ed2460 --- /dev/null +++ b/yazi-shared/src/path/dyn.rs @@ -0,0 +1,9 @@ +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub enum PathDyn<'p> { + Os(&'p std::path::Path), +} + +#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub enum PathBufDyn { + Os(std::path::PathBuf), +} diff --git a/yazi-shared/src/path/inner.rs b/yazi-shared/src/path/inner.rs new file mode 100644 index 00000000..741bd624 --- /dev/null +++ b/yazi-shared/src/path/inner.rs @@ -0,0 +1,13 @@ +pub trait PathInner<'a>: Copy { + fn len(self) -> usize { self.encoded_bytes().len() } + + fn encoded_bytes(self) -> &'a [u8]; +} + +impl<'a> PathInner<'a> for &'a std::ffi::OsStr { + fn encoded_bytes(self) -> &'a [u8] { self.as_encoded_bytes() } +} + +impl<'a> PathInner<'a> for &'a [u8] { + fn encoded_bytes(self) -> &'a [u8] { self } +} diff --git a/yazi-shared/src/path/mod.rs b/yazi-shared/src/path/mod.rs index ff9b6f21..99d255a7 100644 --- a/yazi-shared/src/path/mod.rs +++ b/yazi-shared/src/path/mod.rs @@ -1 +1 @@ -yazi_macro::mod_flat!(traits); +yazi_macro::mod_flat!(buf component components inner path r#dyn traits); diff --git a/yazi-shared/src/path/path.rs b/yazi-shared/src/path/path.rs new file mode 100644 index 00000000..c24b1111 --- /dev/null +++ b/yazi-shared/src/path/path.rs @@ -0,0 +1,81 @@ +use crate::path::{AsPathView, PathBufLike, PathInner}; + +pub trait PathLike<'p> +where + Self: Copy + AsPathView<'p, Self::View<'p>>, +{ + type Inner: PathInner<'p>; + type Owned: PathBufLike + Into; + type View<'a>; + type Components<'a>: AsPathView<'a, Self::View<'a>> + Clone + DoubleEndedIterator; + + fn components(self) -> Self::Components<'p>; + + fn default() -> Self; + + fn encoded_bytes(self) -> &'p [u8]; + + fn extension(self) -> Option; + + fn file_name(self) -> Option; + + fn file_stem(self) -> Option; + + unsafe fn from_encoded_bytes(bytes: &'p [u8]) -> Self; + + #[cfg(unix)] + fn is_hidden(self) -> bool { + self.file_name().map_or(false, |n| n.encoded_bytes().get(0) == Some(&b'.')) + } + + fn join<'a, T>(self, base: T) -> Self::Owned + where + T: AsPathView<'a, Self::View<'a>>; + + fn len(self) -> usize { self.encoded_bytes().len() } + + fn parent(self) -> Option; + + fn strip_prefix<'a, T>(self, base: T) -> Option + where + T: AsPathView<'a, Self::View<'a>>; +} + +impl<'p> PathLike<'p> for &'p std::path::Path { + type Components<'a> = std::path::Components<'a>; + type Inner = &'p std::ffi::OsStr; + type Owned = std::path::PathBuf; + type View<'a> = &'a std::path::Path; + + fn components(self) -> Self::Components<'p> { self.components() } + + fn default() -> Self { std::path::Path::new("") } + + fn encoded_bytes(self) -> &'p [u8] { self.as_os_str().as_encoded_bytes() } + + fn extension(self) -> Option { self.extension() } + + fn file_name(self) -> Option { self.file_name() } + + fn file_stem(self) -> Option { self.file_stem() } + + unsafe fn from_encoded_bytes(bytes: &'p [u8]) -> Self { + std::path::Path::new(unsafe { std::ffi::OsStr::from_encoded_bytes_unchecked(bytes) }) + } + + fn join<'a, T>(self, base: T) -> Self::Owned + where + T: AsPathView<'a, Self::View<'a>>, + { + self.join(base.as_path_view()) + } + + fn parent(self) -> Option { self.parent() } + + fn strip_prefix<'a, T>(self, base: T) -> Option + where + T: AsPathView<'a, Self::View<'a>>, + { + self.strip_prefix(base.as_path_view()).ok() + } +} diff --git a/yazi-shared/src/path/traits.rs b/yazi-shared/src/path/traits.rs index b8750137..734b5e1e 100644 --- a/yazi-shared/src/path/traits.rs +++ b/yazi-shared/src/path/traits.rs @@ -1,147 +1,90 @@ -use std::{ffi::{OsStr, OsString}, path::{Path, PathBuf}}; +use crate::path::PathLike; pub trait AsPath { - fn as_path(&self) -> &(impl ?Sized + PathLike); + fn as_path(&self) -> impl PathLike<'_>; } -pub trait PathLike: AsRef { - type Inner: ?Sized + PathInner; - type Owned: PathBufLike + Into; - type Components<'a>: AsRef + Clone + DoubleEndedIterator - where - Self: 'a; - - fn components(&self) -> Self::Components<'_>; - - fn default() -> &'static Self; - - fn encoded_bytes(&self) -> &[u8]; - - fn extension(&self) -> Option<&Self::Inner>; - - fn file_name(&self) -> Option<&Self::Inner>; - - fn file_stem(&self) -> Option<&Self::Inner>; - - unsafe fn from_encoded_bytes(bytes: &[u8]) -> &Self; - - #[cfg(unix)] - fn is_hidden(&self) -> bool { - self.file_name().map_or(false, |n| n.encoded_bytes().get(0) == Some(&b'.')) - } - - fn join(&self, base: T) -> Self::Owned - where - T: AsRef; - - fn len(&self) -> usize { self.encoded_bytes().len() } - - fn parent(&self) -> Option<&Self>; - - fn strip_prefix(&self, base: T) -> Option<&Self> - where - T: AsRef; +impl AsPath for &std::ffi::OsStr { + fn as_path(&self) -> impl PathLike<'_> { std::path::Path::new(self) } } -pub trait PathBufLike: AsRef + Default + 'static { - type Inner: AsRef; - type InnerRef: ?Sized + PathInner; - type Borrowed: ?Sized + PathLike + AsRef; - - fn encoded_bytes(&self) -> &[u8]; - - unsafe fn from_encoded_bytes(bytes: Vec) -> Self; - - fn into_encoded_bytes(self) -> Vec; - - fn len(&self) -> usize { self.encoded_bytes().len() } - - fn set_file_name(&mut self, name: T) - where - T: AsRef; +impl AsPath for &std::path::Path { + fn as_path(&self) -> impl PathLike<'_> { *self } } -pub trait PathInner { - fn len(&self) -> usize { self.encoded_bytes().len() } - - fn encoded_bytes(&self) -> &[u8]; +impl AsPath for std::path::PathBuf { + fn as_path(&self) -> impl PathLike<'_> { self.as_path() } } -impl AsPath for &OsStr { - fn as_path(&self) -> &(impl ?Sized + PathLike) { Path::new(self) } +impl AsPath for &std::path::PathBuf { + fn as_path(&self) -> impl PathLike<'_> { (*self).as_path() } } -impl AsPath for &Path { - fn as_path(&self) -> &(impl ?Sized + PathLike) { *self } +// --- AsPathView +pub trait AsPathView<'a, T> { + fn as_path_view(self) -> T; } -impl AsPath for PathBuf { - fn as_path(&self) -> &(impl ?Sized + PathLike) { self.as_path() } +impl<'a> AsPathView<'a, &'a std::path::Path> for &'a str { + fn as_path_view(self) -> &'a std::path::Path { std::path::Path::new(self) } } -impl AsPath for &PathBuf { - fn as_path(&self) -> &(impl ?Sized + PathLike) { (*self).as_path() } +impl<'a> AsPathView<'a, &'a std::path::Path> for &'a std::path::Path { + fn as_path_view(self) -> &'a std::path::Path { self } } -impl PathLike for Path { - type Components<'a> = std::path::Components<'a>; - type Inner = OsStr; - type Owned = PathBuf; +impl<'a> AsPathView<'a, &'a std::path::Path> for &'a std::path::PathBuf { + fn as_path_view(self) -> &'a std::path::Path { self } +} - fn components(&self) -> Self::Components<'_> { self.components() } +impl<'a> AsPathView<'a, &'a std::path::Path> for std::path::Components<'a> { + fn as_path_view(self) -> &'a std::path::Path { self.as_path() } +} - fn default() -> &'static Self { Path::new("") } - - fn encoded_bytes(&self) -> &[u8] { self.as_os_str().as_encoded_bytes() } - - fn extension(&self) -> Option<&Self::Inner> { self.extension() } - - fn file_name(&self) -> Option<&Self::Inner> { self.file_name() } - - fn file_stem(&self) -> Option<&Self::Inner> { self.file_stem() } - - unsafe fn from_encoded_bytes(bytes: &[u8]) -> &Self { - Self::new(unsafe { Self::Inner::from_encoded_bytes_unchecked(bytes) }) - } - - fn join(&self, base: T) -> Self::Owned - where - T: AsRef, - { - self.join(base) - } - - fn parent(&self) -> Option<&Self> { self.parent() } - - fn strip_prefix(&self, base: T) -> Option<&Self> - where - T: AsRef, - { - self.strip_prefix(base).ok() +impl<'a> AsPathView<'a, super::PathDyn<'a>> for &'a super::PathBufDyn { + fn as_path_view(self) -> super::PathDyn<'a> { + match self { + super::PathBufDyn::Os(p) => super::PathDyn::Os(p.as_path()), + } } } -impl PathBufLike for PathBuf { - type Borrowed = Path; - type Inner = OsString; - type InnerRef = OsStr; - - fn encoded_bytes(&self) -> &[u8] { self.as_os_str().as_encoded_bytes() } - - unsafe fn from_encoded_bytes(bytes: Vec) -> Self { - Self::from(unsafe { Self::Inner::from_encoded_bytes_unchecked(bytes) }) - } - - fn into_encoded_bytes(self) -> Vec { self.into_os_string().into_encoded_bytes() } - - fn set_file_name(&mut self, name: T) - where - T: AsRef, - { - self.set_file_name(name); - } +impl<'a> AsPathView<'a, &'a std::path::Path> for crate::loc::Loc<'a, &'a std::path::Path> { + fn as_path_view(self) -> &'a std::path::Path { *self } } -impl PathInner for OsStr { - fn encoded_bytes(&self) -> &[u8] { self.as_encoded_bytes() } +// --- ToPathOwned +pub trait ToPathOwned { + fn to_path_owned(&self) -> T; +} + +impl ToPathOwned for std::path::Path { + fn to_path_owned(&self) -> std::path::PathBuf { self.to_owned() } +} + +impl ToPathOwned for &T +where + T: ?Sized + ToPathOwned, +{ + fn to_path_owned(&self) -> U { (*self).to_path_owned() } +} + +// --- AsInnerView +pub trait AsInnerView<'a, T> { + fn as_inner_view(&'a self) -> T; +} + +impl<'a> AsInnerView<'a, &'a std::ffi::OsStr> for std::ffi::OsStr { + fn as_inner_view(&'a self) -> &'a std::ffi::OsStr { self } +} + +impl<'a> AsInnerView<'a, &'a std::ffi::OsStr> for std::ffi::OsString { + fn as_inner_view(&'a self) -> &'a std::ffi::OsStr { self } +} + +impl<'a, T, U> AsInnerView<'a, U> for &T +where + T: ?Sized + AsInnerView<'a, U>, +{ + fn as_inner_view(&'a self) -> U { (*self).as_inner_view() } } diff --git a/yazi-shared/src/url/buf.rs b/yazi-shared/src/url/buf.rs index 204313df..59fe12b7 100644 --- a/yazi-shared/src/url/buf.rs +++ b/yazi-shared/src/url/buf.rs @@ -95,7 +95,7 @@ impl UrlBuf { } #[inline] - pub fn set_name(&mut self, name: impl AsRef) { self.loc.set_name(name); } + pub fn set_name(&mut self, name: impl AsRef) { self.loc.set_name(name.as_ref()); } #[inline] pub fn rebase(&self, base: &Path) -> Self { @@ -125,14 +125,14 @@ impl UrlBuf { #[inline] pub fn to_search(&self, domain: impl AsRef) -> Self { Self { - loc: LocBuf::zeroed(self.loc.to_path()), + loc: LocBuf::::zeroed(self.loc.to_path()), scheme: Scheme::Search(Pool::::intern(domain)), } } #[inline] pub fn into_search(mut self, domain: impl AsRef) -> Self { - self.loc = LocBuf::zeroed(self.loc.into_path()); + self.loc = LocBuf::::zeroed(self.loc.into_path()); self.scheme = Scheme::Search(Pool::::intern(domain)); self } diff --git a/yazi-shared/src/url/cow.rs b/yazi-shared/src/url/cow.rs index e7330797..d18e6199 100644 --- a/yazi-shared/src/url/cow.rs +++ b/yazi-shared/src/url/cow.rs @@ -49,12 +49,14 @@ impl<'a> TryFrom<&'a [u8]> for UrlCow<'a> { let (scheme, path, port) = Self::parse(value)?; Ok(match (path, port) { - (Cow::Borrowed(p), None) => Self::Borrowed { loc: Loc::from(p), scheme }, + (Cow::Borrowed(p), None) => Self::Borrowed { loc: Loc::bare(p), scheme }, (Cow::Borrowed(p), Some((uri, urn))) => { Self::Borrowed { loc: Loc::with(p, uri, urn)?, scheme } } (Cow::Owned(p), None) => Self::Owned { loc: LocBuf::from(p), scheme }, - (Cow::Owned(p), Some((uri, urn))) => Self::Owned { loc: LocBuf::with(p, uri, urn)?, scheme }, + (Cow::Owned(p), Some((uri, urn))) => { + Self::Owned { loc: LocBuf::::with(p, uri, urn)?, scheme } + } }) } } diff --git a/yazi-shared/src/url/traits.rs b/yazi-shared/src/url/traits.rs index 0f8a2937..6c7aec51 100644 --- a/yazi-shared/src/url/traits.rs +++ b/yazi-shared/src/url/traits.rs @@ -1,6 +1,6 @@ use std::{borrow::Cow, ffi::OsStr, path::{Path, PathBuf}}; -use crate::{scheme::{AsScheme, SchemeRef}, url::{Components, Display, Url, UrlBuf, UrlCow}}; +use crate::{loc::Loc, scheme::{AsScheme, SchemeRef}, url::{Components, Display, Url, UrlBuf, UrlCow}}; // --- AsUrl pub trait AsUrl { @@ -9,7 +9,7 @@ pub trait AsUrl { impl AsUrl for Path { #[inline] - fn as_url(&self) -> Url<'_> { Url { loc: self.into(), scheme: SchemeRef::Regular } } + fn as_url(&self) -> Url<'_> { Url { loc: Loc::bare(self), scheme: SchemeRef::Regular } } } impl AsUrl for &Path { diff --git a/yazi-shared/src/url/url.rs b/yazi-shared/src/url/url.rs index b71ce3c4..3bd2ea93 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}, path::Path}; +use std::{borrow::Cow, ffi::OsStr, fmt::{Debug, Formatter}, path::{Path, PathBuf}}; use hashbrown::Equivalent; @@ -34,7 +34,7 @@ impl Debug for Url<'_> { impl<'a> Url<'a> { #[inline] pub fn regular + ?Sized>(path: &'a T) -> Self { - Self { loc: path.as_ref().into(), scheme: SchemeRef::Regular } + Self { loc: Loc::bare(path.as_ref()), scheme: SchemeRef::Regular } } #[inline] @@ -42,7 +42,7 @@ impl<'a> Url<'a> { #[inline] pub fn into_regular(self) -> Self { - Self { loc: self.loc.as_path().into(), scheme: SchemeRef::Regular } + Self { loc: Loc::bare(self.loc.as_path()), scheme: SchemeRef::Regular } } #[inline] @@ -71,8 +71,8 @@ impl<'a> Url<'a> { let loc = match self.scheme { S::Regular => join.into(), - S::Search(_) => LocBuf::new(join, self.loc.base(), self.loc.base()), - S::Archive(_) => LocBuf::floated(join, self.loc.base()), + S::Search(_) => LocBuf::::new(join, self.loc.base(), self.loc.base()), + S::Archive(_) => LocBuf::::floated(join, self.loc.base()), S::Sftp(_) => join.into(), }; @@ -134,7 +134,7 @@ impl<'a> Url<'a> { return None; } - let loc: Loc = self.loc.base().into(); + let loc = Loc::bare(self.loc.base()); Some(match self.scheme { S::Regular => Self { loc, scheme: S::Regular }, S::Search(_) => Self { loc, scheme: self.scheme }, @@ -151,11 +151,11 @@ impl<'a> Url<'a> { Some(match self.scheme { // Regular - S::Regular => Self { loc: parent.into(), scheme: S::Regular }, + S::Regular => Self { loc: Loc::bare(parent), scheme: S::Regular }, // Search S::Search(_) if uri.as_os_str().is_empty() => { - Self { loc: parent.into(), scheme: S::Regular } + Self { loc: Loc::bare(parent), scheme: S::Regular } } S::Search(_) => { Self { loc: Loc::new(parent, self.loc.base(), self.loc.base()), scheme: self.scheme } @@ -163,7 +163,7 @@ impl<'a> Url<'a> { // Archive S::Archive(_) if uri.as_os_str().is_empty() => { - Self { loc: parent.into(), scheme: S::Regular } + Self { loc: Loc::bare(parent), scheme: S::Regular } } S::Archive(_) if uri.components().nth(1).is_none() => { Self { loc: Loc::zeroed(parent), scheme: self.scheme } @@ -171,7 +171,7 @@ impl<'a> Url<'a> { S::Archive(_) => Self { loc: Loc::floated(parent, self.loc.base()), scheme: self.scheme }, // SFTP - S::Sftp(_) => Self { loc: parent.into(), scheme: self.scheme }, + S::Sftp(_) => Self { loc: Loc::bare(parent), scheme: self.scheme }, }) }