diff --git a/yazi-actor/src/cmp/trigger.rs b/yazi-actor/src/cmp/trigger.rs index 0a39868a..a5ac077d 100644 --- a/yazi-actor/src/cmp/trigger.rs +++ b/yazi-actor/src/cmp/trigger.rs @@ -1,11 +1,11 @@ -use std::{ffi::OsString, mem, path::MAIN_SEPARATOR_STR}; +use std::{ffi::OsString, mem, path::{MAIN_SEPARATOR_STR, PathBuf}}; use anyhow::Result; use yazi_fs::{CWD, path::expand_url, provider::{DirReader, FileHolder}}; use yazi_macro::{act, render, succ}; use yazi_parser::cmp::{CmpItem, ShowOpt, TriggerOpt}; use yazi_proxy::CmpProxy; -use yazi_shared::{OsStrSplit, data::Data, natsort, scheme::SchemeLike, url::{UrlBuf, UrlCow, UrnBuf}}; +use yazi_shared::{OsStrSplit, data::Data, natsort, scheme::SchemeLike, url::{UrlBuf, UrlCow}}; use yazi_vfs::provider; use crate::{Actor, Ctx}; @@ -67,7 +67,7 @@ impl Actor for Trigger { } impl Trigger { - fn split_url(s: &str) -> Option<(UrlBuf, UrnBuf)> { + fn split_url(s: &str) -> Option<(UrlBuf, PathBuf)> { let (scheme, path, ..) = UrlCow::parse(s.as_bytes()).ok()?; if scheme.is_local() && path.as_os_str() == "~" { @@ -91,16 +91,16 @@ impl Trigger { #[cfg(test)] mod tests { - use yazi_shared::url::{UrlLike, Urn}; + use yazi_shared::url::UrlLike; use super::*; fn compare(s: &str, parent: &str, child: &str) { let (mut p, c) = Trigger::split_url(s).unwrap(); if let Some(u) = p.strip_prefix(yazi_fs::CWD.load().as_ref()) { - p = UrlBuf::from(&**u); + p = UrlBuf::from(u); } - assert_eq!((p, c.as_urn()), (parent.parse().unwrap(), Urn::new(child))); + assert_eq!((p, c.to_str().unwrap()), (parent.parse().unwrap(), child)); } #[cfg(unix)] diff --git a/yazi-binding/src/url.rs b/yazi-binding/src/url.rs index f1856eaa..46bb2d63 100644 --- a/yazi-binding/src/url.rs +++ b/yazi-binding/src/url.rs @@ -4,7 +4,7 @@ use mlua::{AnyUserData, ExternalError, FromLua, Lua, MetaMethod, UserData, UserD use yazi_fs::{FsHash64, FsHash128}; use yazi_shared::{IntoOsStr, scheme::SchemeLike, url::{AsUrl, UrlCow, UrlLike}}; -use crate::{Scheme, Urn, cached_field, deprecate}; +use crate::{Scheme, cached_field, deprecate}; pub type UrlRef = UserDataRef; @@ -108,7 +108,10 @@ impl UserData for Url { me.ext().map(|s| lua.create_string(s.as_encoded_bytes())).transpose() }); cached_field!(fields, parent, |_, me| Ok(me.parent().map(Self::new))); - cached_field!(fields, urn, |_, me| Ok(Urn::new(me.urn()))); + cached_field!(fields, urn, |_, me| { + // FIXME: remove type inference + Ok(super::Path::::new(me.urn())) + }); cached_field!(fields, base, |_, me| Ok(me.base().map(Self::new))); cached_field!(fields, scheme, |_, me| Ok(Scheme::new(&me.scheme))); diff --git a/yazi-binding/src/urn.rs b/yazi-binding/src/urn.rs index d6851486..f770420e 100644 --- a/yazi-binding/src/urn.rs +++ b/yazi-binding/src/urn.rs @@ -3,43 +3,34 @@ use std::{ops::Deref, path::PathBuf}; use mlua::{ExternalError, FromLua, Lua, UserData, Value}; use yazi_shared::path::PathBufLike; -pub struct Urn { - inner: yazi_shared::url::UrnBuf

, -} +pub struct Path(pub P); -impl

Deref for Urn

+impl

Deref for Path

where P: PathBufLike, { - type Target = yazi_shared::url::UrnBuf

; + type Target = P; - fn deref(&self) -> &Self::Target { &self.inner } + fn deref(&self) -> &Self::Target { &self.0 } } -impl

From> for yazi_shared::url::UrnBuf

+impl

Path

where P: PathBufLike, { - fn from(value: Urn

) -> Self { value.inner } + pub fn new(urn: impl Into

) -> Self { Self(urn.into()) } } -impl

Urn

-where - P: PathBufLike, -{ - pub fn new(urn: impl Into>) -> Self { Self { inner: urn.into() } } -} - -impl

FromLua for Urn

+impl

FromLua for Path

where P: PathBufLike, { fn from_lua(value: Value, _: &Lua) -> mlua::Result { Ok(match value { Value::UserData(ud) => ud.take()?, - _ => Err("Expected a Urn".into_lua_err())?, + _ => Err("Expected a Path".into_lua_err())?, }) } } -impl

UserData for Urn

where P: PathBufLike {} +impl

UserData for Path

where P: PathBufLike {} diff --git a/yazi-boot/src/boot.rs b/yazi-boot/src/boot.rs index a45f1bae..68f3610e 100644 --- a/yazi-boot/src/boot.rs +++ b/yazi-boot/src/boot.rs @@ -4,13 +4,13 @@ use futures::executor::block_on; use hashbrown::HashSet; use serde::Serialize; use yazi_fs::{CWD, Xdg, path::expand_url}; -use yazi_shared::url::{UrlBuf, UrlCow, UrlLike, UrnBuf}; +use yazi_shared::url::{UrlBuf, UrlCow, UrlLike}; use yazi_vfs::provider; #[derive(Debug, Default, Serialize)] pub struct Boot { pub cwds: Vec, - pub files: Vec, + pub files: Vec, pub local_events: HashSet, pub remote_events: HashSet, @@ -22,25 +22,25 @@ pub struct Boot { } impl Boot { - async fn parse_entries(entries: &[UrlBuf]) -> (Vec, Vec) { + async fn parse_entries(entries: &[UrlBuf]) -> (Vec, Vec) { if entries.is_empty() { - return (vec![CWD.load().as_ref().clone()], vec![UrnBuf::default()]); + return (vec![CWD.load().as_ref().clone()], vec![PathBuf::default()]); } - async fn go(entry: &UrlBuf) -> (UrlBuf, UrnBuf) { + async fn go(entry: &UrlBuf) -> (UrlBuf, PathBuf) { let mut entry = expand_url(entry); if let Ok(u @ UrlCow::Owned { .. }) = provider::absolute(&entry).await { entry = u.into_owned(); } let Some((parent, child)) = entry.pair() else { - return (entry, UrnBuf::default()); + return (entry, PathBuf::default()); }; if provider::metadata(&entry).await.is_ok_and(|m| m.is_file()) { (parent.into(), child.to_owned()) } else { - (entry, UrnBuf::default()) + (entry, PathBuf::default()) } } diff --git a/yazi-core/src/tab/finder.rs b/yazi-core/src/tab/finder.rs index 54402f7a..509bbc46 100644 --- a/yazi-core/src/tab/finder.rs +++ b/yazi-core/src/tab/finder.rs @@ -1,13 +1,15 @@ +use std::path::{Path, PathBuf}; + use anyhow::Result; use hashbrown::HashMap; use yazi_fs::{Files, Filter, FilterCase}; -use yazi_shared::url::{UrlBuf, Urn, UrnBuf}; +use yazi_shared::url::UrlBuf; use crate::tab::Folder; pub struct Finder { pub filter: Filter, - pub matched: HashMap, + pub matched: HashMap, lock: FinderLock, } @@ -76,7 +78,7 @@ impl Finder { } impl Finder { - pub fn matched_idx(&self, folder: &Folder, urn: &Urn) -> Option { + pub fn matched_idx(&self, folder: &Folder, urn: &Path) -> Option { if self.lock == *folder { self.matched.get(urn).copied() } else { None } } } diff --git a/yazi-core/src/tab/folder.rs b/yazi-core/src/tab/folder.rs index b7e3cb32..2a2cc6ba 100644 --- a/yazi-core/src/tab/folder.rs +++ b/yazi-core/src/tab/folder.rs @@ -1,4 +1,4 @@ -use std::mem; +use std::{mem, path::{Path, PathBuf}}; use yazi_config::{LAYOUT, YAZI}; use yazi_dds::Pubsub; @@ -6,7 +6,7 @@ use yazi_fs::{File, Files, FilesOp, FolderStage, cha::Cha}; use yazi_macro::err; use yazi_parser::Step; use yazi_proxy::MgrProxy; -use yazi_shared::{Id, url::{UrlBuf, Urn, UrnBuf}}; +use yazi_shared::{Id, url::UrlBuf}; use yazi_widgets::Scrollable; pub struct Folder { @@ -19,7 +19,7 @@ pub struct Folder { pub cursor: usize, pub page: usize, - pub trace: Option, + pub trace: Option, } impl Default for Folder { @@ -108,7 +108,7 @@ impl Folder { b } - pub fn hover(&mut self, urn: &Urn) -> bool { + pub fn hover(&mut self, urn: &Path) -> bool { if self.hovered().map(|h| h.urn()) == Some(urn) { return self.arrow(0); } @@ -117,7 +117,7 @@ impl Folder { self.arrow(new - self.cursor as isize) } - pub fn repos(&mut self, urn: Option<&Urn>) -> bool { + pub fn repos(&mut self, urn: Option<&Path>) -> bool { if let Some(u) = urn { self.hover(u) } else if let Some(u) = &self.trace { diff --git a/yazi-dds/src/sendable.rs b/yazi-dds/src/sendable.rs index a1703985..157e6b94 100644 --- a/yazi-dds/src/sendable.rs +++ b/yazi-dds/src/sendable.rs @@ -46,8 +46,8 @@ impl Sendable { Some(t) if t == TypeId::of::() => { Data::Url(ud.take::()?.into()) } - Some(t) if t == TypeId::of::() => { - Data::Urn(ud.take::()?.into()) + Some(t) if t == TypeId::of::>() => { + Data::Path(ud.take::>()?.0) } Some(t) if t == TypeId::of::() => { Data::Id(**ud.borrow::()?) @@ -83,7 +83,7 @@ impl Sendable { Value::Table(tbl) } Data::Url(u) => yazi_binding::Url::new(u).into_lua(lua)?, - Data::Urn(u) => yazi_binding::Urn::new(u).into_lua(lua)?, + Data::Path(u) => yazi_binding::Path::::new(u).into_lua(lua)?, Data::Any(a) => { if a.is::() { lua.create_any_userdata(*a.downcast::().unwrap())?.into_lua(lua)? @@ -121,7 +121,7 @@ impl Sendable { } Data::Id(i) => yazi_binding::Id(*i).into_lua(lua)?, Data::Url(u) => yazi_binding::Url::new(u.clone()).into_lua(lua)?, - Data::Urn(u) => yazi_binding::Urn::new(u.clone()).into_lua(lua)?, + Data::Path(u) => yazi_binding::Path::::new(u).into_lua(lua)?, Data::Bytes(b) => Value::String(lua.create_string(b)?), Data::Any(a) => { if let Some(t) = a.downcast_ref::() { @@ -214,8 +214,8 @@ impl Sendable { Some(t) if t == TypeId::of::() => { DataKey::Url(ud.take::()?.into()) } - Some(t) if t == TypeId::of::() => { - DataKey::Urn(ud.take::()?.into()) + Some(t) if t == TypeId::of::() => { + DataKey::Path(ud.take::()?.0) } Some(t) if t == TypeId::of::() => { DataKey::Id(**ud.borrow::()?) @@ -230,7 +230,7 @@ impl Sendable { fn key_to_value(lua: &Lua, key: DataKey) -> mlua::Result { match key { DataKey::Url(u) => yazi_binding::Url::new(u).into_lua(lua), - DataKey::Urn(u) => yazi_binding::Urn::new(u).into_lua(lua), + DataKey::Path(u) => yazi_binding::Path::::new(u).into_lua(lua), _ => Self::key_to_value_ref(lua, &key), } } @@ -244,7 +244,7 @@ impl Sendable { DataKey::String(s) => Value::String(lua.create_string(s.as_ref())?), DataKey::Id(i) => yazi_binding::Id(*i).into_lua(lua)?, DataKey::Url(u) => yazi_binding::Url::new(u.clone()).into_lua(lua)?, - DataKey::Urn(u) => yazi_binding::Urn::new(u.clone()).into_lua(lua)?, + DataKey::Path(u) => yazi_binding::Path::::new(u).into_lua(lua)?, DataKey::Bytes(b) => Value::String(lua.create_string(b)?), }) } diff --git a/yazi-fs/src/cha/cha.rs b/yazi-fs/src/cha/cha.rs index 3a519814..469e4f54 100644 --- a/yazi-fs/src/cha/cha.rs +++ b/yazi-fs/src/cha/cha.rs @@ -59,6 +59,8 @@ impl Cha { let mut kind = ChaKind::DUMMY; let mode = r#type.map(ChaMode::from_bare).unwrap_or_default(); + #[cfg(unix)] + use yazi_shared::path::PathLike; #[cfg(unix)] if _url.as_url().urn().is_hidden() { kind |= ChaKind::HIDDEN; diff --git a/yazi-fs/src/file.rs b/yazi-fs/src/file.rs index 123376dc..34612f67 100644 --- a/yazi-fs/src/file.rs +++ b/yazi-fs/src/file.rs @@ -1,6 +1,6 @@ use std::{ffi::OsStr, hash::{Hash, Hasher}, ops::Deref, path::{Path, PathBuf}}; -use yazi_shared::url::{Uri, UrlBuf, UrlLike, Urn}; +use yazi_shared::url::{UrlBuf, UrlLike}; use crate::cha::{Cha, ChaType}; @@ -37,10 +37,10 @@ impl File { pub fn url_owned(&self) -> UrlBuf { self.url.to_owned() } #[inline] - pub fn uri(&self) -> &Uri { self.url.uri() } + pub fn uri(&self) -> &Path { self.url.uri() } #[inline] - pub fn urn(&self) -> &Urn { self.url.urn() } + pub fn urn(&self) -> &Path { self.url.urn() } #[inline] pub fn name(&self) -> Option<&OsStr> { self.url.name() } diff --git a/yazi-fs/src/files.rs b/yazi-fs/src/files.rs index f014382d..67e59754 100644 --- a/yazi-fs/src/files.rs +++ b/yazi-fs/src/files.rs @@ -1,7 +1,7 @@ -use std::{mem, ops::{Deref, DerefMut, Not}}; +use std::{mem, ops::{Deref, DerefMut, Not}, path::{Path, PathBuf}}; use hashbrown::{HashMap, HashSet}; -use yazi_shared::{Id, url::{Urn, UrnBuf}}; +use yazi_shared::Id; use super::{FilesSorter, Filter}; use crate::{FILES_TICKET, File, SortBy}; @@ -14,7 +14,7 @@ pub struct Files { version: u64, pub revision: u64, - pub sizes: HashMap, + pub sizes: HashMap, sorter: FilesSorter, filter: Option, @@ -69,7 +69,7 @@ impl Files { } } - pub fn update_size(&mut self, mut sizes: HashMap) { + pub fn update_size(&mut self, mut sizes: HashMap) { if sizes.len() <= 50 { sizes.retain(|k, v| self.sizes.get(k) != Some(v)); } @@ -120,19 +120,18 @@ impl Files { } #[cfg(unix)] - pub fn update_deleting(&mut self, urns: HashSet) -> Vec { + pub fn update_deleting(&mut self, urns: HashSet) -> Vec { + use yazi_shared::path::PathLike; if urns.is_empty() { return vec![]; } let (mut hidden, mut items) = if let Some(filter) = &self.filter { - urns - .into_iter() - .partition(|u| (!self.show_hidden && u.as_urn().is_hidden()) || !filter.matches(u.as_urn())) + urns.into_iter().partition(|u| (!self.show_hidden && u.is_hidden()) || !filter.matches(u)) } else if self.show_hidden { (HashSet::new(), urns) } else { - urns.into_iter().partition(|u| u.as_urn().is_hidden()) + urns.into_iter().partition(|u| u.is_hidden()) }; let mut deleted = Vec::with_capacity(items.len()); @@ -156,7 +155,7 @@ impl Files { } #[cfg(windows)] - pub fn update_deleting(&mut self, mut urns: HashSet) -> Vec { + pub fn update_deleting(&mut self, mut urns: HashSet) -> Vec { let mut deleted = Vec::with_capacity(urns.len()); if !urns.is_empty() { let mut i = 0; @@ -179,8 +178,8 @@ impl Files { pub fn update_updating( &mut self, - files: HashMap, - ) -> (HashMap, HashMap) { + files: HashMap, + ) -> (HashMap, HashMap) { if files.is_empty() { return Default::default(); } @@ -222,7 +221,7 @@ impl Files { (hidden, items) } - pub fn update_upserting(&mut self, files: HashMap) { + pub fn update_upserting(&mut self, files: HashMap) { if files.is_empty() { return; } @@ -271,7 +270,7 @@ impl Files { impl Files { // --- Items #[inline] - pub fn position(&self, urn: &Urn) -> Option { self.iter().position(|f| urn == f.urn()) } + pub fn position(&self, urn: &Path) -> Option { self.iter().position(|f| urn == f.urn()) } // --- Ticket #[inline] diff --git a/yazi-fs/src/filter.rs b/yazi-fs/src/filter.rs index e782026a..8bb1394e 100644 --- a/yazi-fs/src/filter.rs +++ b/yazi-fs/src/filter.rs @@ -2,7 +2,7 @@ use std::{ffi::OsStr, fmt::Display, ops::Range}; use anyhow::Result; use regex::bytes::{Regex, RegexBuilder}; -use yazi_shared::{event::Cmd, url::Urn}; +use yazi_shared::{event::Cmd, path::{AsPath, PathLike}}; pub struct Filter { raw: String, @@ -24,7 +24,12 @@ impl Filter { #[inline] #[allow(private_bounds)] - pub fn matches(&self, name: impl Needle) -> bool { self.regex.is_match(name.needle()) } + pub fn matches(&self, name: T) -> bool + where + T: AsPath, + { + self.regex.is_match(name.as_path().encoded_bytes()) + } #[inline] pub fn highlighted(&self, name: impl AsRef) -> Option>> { @@ -57,16 +62,3 @@ impl From<&Cmd> for FilterCase { } } } - -// --- Needle -trait Needle { - fn needle(&self) -> &[u8]; -} - -impl Needle for &OsStr { - fn needle(&self) -> &[u8] { self.as_encoded_bytes() } -} - -impl Needle for &Urn { - fn needle(&self) -> &[u8] { self.encoded_bytes() } -} diff --git a/yazi-fs/src/op.rs b/yazi-fs/src/op.rs index f2b37d46..ed9414a8 100644 --- a/yazi-fs/src/op.rs +++ b/yazi-fs/src/op.rs @@ -1,8 +1,8 @@ -use std::path::Path; +use std::path::{Path, PathBuf}; use hashbrown::{HashMap, HashSet}; use yazi_macro::relay; -use yazi_shared::{Id, Ids, url::{UrlBuf, UrlLike, UrnBuf}}; +use yazi_shared::{Id, Ids, url::{UrlBuf, UrlLike}}; use super::File; use crate::{cha::Cha, error::Error}; @@ -14,13 +14,13 @@ pub enum FilesOp { Full(UrlBuf, Vec, Cha), Part(UrlBuf, Vec, Id), Done(UrlBuf, Cha, Id), - Size(UrlBuf, HashMap), + Size(UrlBuf, HashMap), IOErr(UrlBuf, Error), Creating(UrlBuf, Vec), - Deleting(UrlBuf, HashSet), - Updating(UrlBuf, HashMap), - Upserting(UrlBuf, HashMap), + Deleting(UrlBuf, HashSet), + Updating(UrlBuf, HashMap), + Upserting(UrlBuf, HashMap), } impl FilesOp { diff --git a/yazi-fs/src/path/clean.rs b/yazi-fs/src/path/clean.rs index 3d893d78..c4dd7021 100644 --- a/yazi-fs/src/path/clean.rs +++ b/yazi-fs/src/path/clean.rs @@ -4,8 +4,11 @@ use yazi_shared::{loc::LocBuf, url::{UrlBuf, UrlCow}}; pub fn clean_url<'a>(url: impl Into>) -> UrlBuf { let cow: UrlCow = url.into(); - let (path, uri, urn) = - clean_path_impl(&cow.loc(), cow.loc().base().count(), cow.loc().trail().count()); + let (path, uri, urn) = clean_path_impl( + &cow.loc(), + cow.loc().base().components().count(), + cow.loc().trail().components().count(), + ); 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 a36a54c1..95fa8f26 100644 --- a/yazi-fs/src/path/expand.rs +++ b/yazi-fs/src/path/expand.rs @@ -19,8 +19,8 @@ fn expand_url_impl<'a>(url: Url<'a>) -> UrlCow<'a> { let rest_diff = n_rest.components().count() as isize - o_rest.components().count() as isize; let urn_diff = n_urn.components().count() as isize - o_urn.components().count() as isize; - let uri_count = url.uri().count() as isize; - let urn_count = url.urn().count() as isize; + let uri_count = url.uri().components().count() as isize; + let urn_count = url.urn().components().count() as isize; let loc = LocBuf::with( PathBuf::from_iter([n_base, n_rest, n_urn]), @@ -83,15 +83,19 @@ pub fn absolute_url<'a>(url: Url<'a>) -> UrlCow<'a> { let add = home.components().count() - 1; // Home root ("~") has offset by the absolute root ("/") let loc = LocBuf::with( home.join(rest), - url.uri().count() + if url.has_base() { 0 } else { add }, - url.urn().count() + if url.has_trail() { 0 } else { add }, + url.uri().components().count() + if url.has_base() { 0 } else { add }, + url.urn().components().count() + if url.has_trail() { 0 } else { add }, ) .expect("Failed to create Loc from home directory"); UrlBuf { loc, scheme: url.scheme.into() }.into() } else if !url.is_absolute() { let cwd = CWD.path(); - let loc = LocBuf::with(cwd.join(url.loc), url.uri().count(), url.urn().count()) - .expect("Failed to create Loc from relative path"); + let loc = LocBuf::with( + cwd.join(url.loc), + url.uri().components().count(), + url.urn().components().count(), + ) + .expect("Failed to create Loc from relative path"); UrlBuf { loc, scheme: url.scheme.into() }.into() } else { url.into() diff --git a/yazi-fs/src/sorter.rs b/yazi-fs/src/sorter.rs index 109dff4e..cd7ede81 100644 --- a/yazi-fs/src/sorter.rs +++ b/yazi-fs/src/sorter.rs @@ -1,7 +1,7 @@ -use std::cmp::Ordering; +use std::{cmp::Ordering, path::PathBuf}; use hashbrown::HashMap; -use yazi_shared::{LcgRng, natsort, translit::Transliterator, url::{UrlLike, UrnBuf}}; +use yazi_shared::{LcgRng, natsort, path::PathLike, translit::Transliterator, url::UrlLike}; use crate::{File, SortBy}; @@ -15,7 +15,7 @@ pub struct FilesSorter { } impl FilesSorter { - pub(super) fn sort(&self, items: &mut [File], sizes: &HashMap) { + pub(super) fn sort(&self, items: &mut [File], sizes: &HashMap) { if items.is_empty() { return; } diff --git a/yazi-parser/src/cmp/show.rs b/yazi-parser/src/cmp/show.rs index 5af4e9e9..13508a7d 100644 --- a/yazi-parser/src/cmp/show.rs +++ b/yazi-parser/src/cmp/show.rs @@ -1,14 +1,14 @@ -use std::{ffi::OsString, path::MAIN_SEPARATOR_STR}; +use std::{ffi::OsString, path::{MAIN_SEPARATOR_STR, PathBuf}}; use anyhow::bail; use mlua::{ExternalError, FromLua, IntoLua, Lua, Value}; -use yazi_shared::{Id, event::CmdCow, url::{UrlBuf, UrnBuf}}; +use yazi_shared::{Id, event::CmdCow, url::UrlBuf}; #[derive(Debug, Default)] pub struct ShowOpt { pub cache: Vec, pub cache_name: UrlBuf, - pub word: UrnBuf, + pub word: PathBuf, pub ticket: Id, } diff --git a/yazi-parser/src/mgr/hover.rs b/yazi-parser/src/mgr/hover.rs index 8b0aeb16..359a2659 100644 --- a/yazi-parser/src/mgr/hover.rs +++ b/yazi-parser/src/mgr/hover.rs @@ -1,13 +1,14 @@ +use std::path::PathBuf; + use mlua::{ExternalError, FromLua, IntoLua, Lua, Value}; -use yazi_shared::url::UrnBuf; #[derive(Debug, Default)] pub struct HoverOpt { - pub urn: Option, + pub urn: Option, } -impl From> for HoverOpt { - fn from(urn: Option) -> Self { Self { urn } } +impl From> for HoverOpt { + fn from(urn: Option) -> Self { Self { urn } } } impl FromLua for HoverOpt { diff --git a/yazi-plugin/src/fs/op.rs b/yazi-plugin/src/fs/op.rs index 0fb91927..e2cb6c7d 100644 --- a/yazi-plugin/src/fs/op.rs +++ b/yazi-plugin/src/fs/op.rs @@ -1,5 +1,5 @@ use mlua::{IntoLua, Lua, Table}; -use yazi_binding::{Cha, File, Id, Url, Urn}; +use yazi_binding::{Cha, File, Id, Path, Url}; pub(super) struct FilesOp(yazi_fs::FilesOp); @@ -34,8 +34,8 @@ impl FilesOp { Ok(Self(yazi_fs::FilesOp::Size( url.into(), sizes - .pairs::() - .map(|r| r.map(|(urn, size)| (urn.into(), size))) + .pairs::() + .map(|r| r.map(|(urn, size)| (urn.0, size))) .collect::>()?, ))) } diff --git a/yazi-shared/src/data/data.rs b/yazi-shared/src/data/data.rs index ba8ab6db..856ce226 100644 --- a/yazi-shared/src/data/data.rs +++ b/yazi-shared/src/data/data.rs @@ -1,10 +1,10 @@ -use std::{any::Any, borrow::Cow}; +use std::{any::Any, borrow::Cow, path::PathBuf}; use anyhow::{Result, bail}; use hashbrown::HashMap; use serde::{Deserialize, Serialize}; -use crate::{Id, SStr, data::DataKey, url::{UrlBuf, UrlCow, UrnBuf}}; +use crate::{Id, SStr, data::DataKey, url::{UrlBuf, UrlCow}}; // --- Data #[derive(Debug, Deserialize, Serialize)] @@ -21,7 +21,7 @@ pub enum Data { #[serde(skip_deserializing)] Url(UrlBuf), #[serde(skip_deserializing)] - Urn(UrnBuf), + Path(PathBuf), #[serde(skip)] Bytes(Vec), #[serde(skip)] diff --git a/yazi-shared/src/data/key.rs b/yazi-shared/src/data/key.rs index 7faa3724..ac67a8f1 100644 --- a/yazi-shared/src/data/key.rs +++ b/yazi-shared/src/data/key.rs @@ -1,9 +1,9 @@ -use std::borrow::Cow; +use std::{borrow::Cow, path::PathBuf}; use ordered_float::OrderedFloat; use serde::{Deserialize, Serialize, de}; -use crate::{Id, SStr, url::{UrlBuf, UrlCow, UrnBuf}}; +use crate::{Id, SStr, url::{UrlBuf, UrlCow}}; #[derive(Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[serde(untagged)] @@ -18,7 +18,7 @@ pub enum DataKey { #[serde(skip_deserializing)] Url(UrlBuf), #[serde(skip_deserializing)] - Urn(UrnBuf), + Path(PathBuf), #[serde(skip)] Bytes(Vec), } diff --git a/yazi-shared/src/loc/buf.rs b/yazi-shared/src/loc/buf.rs index bc14fbde..b2c6bd72 100644 --- a/yazi-shared/src/loc/buf.rs +++ b/yazi-shared/src/loc/buf.rs @@ -2,7 +2,7 @@ use std::{cmp, ffi::OsStr, fmt::{self, Debug, Formatter}, hash::{Hash, Hasher}, use anyhow::Result; -use crate::{loc::Loc, path::{PathBufLike, PathLike}, url::{Uri, Urn}}; +use crate::{loc::Loc, path::{PathBufLike, PathLike}}; #[derive(Clone, Default, Eq)] pub struct LocBuf { @@ -215,19 +215,19 @@ where P: PathBufLike, { #[inline] - pub fn uri(&self) -> &Uri { self.as_loc().uri() } + pub fn uri(&self) -> &P::Borrowed { self.as_loc().uri() } #[inline] - pub fn urn(&self) -> &Urn { self.as_loc().urn() } + pub fn urn(&self) -> &P::Borrowed { self.as_loc().urn() } #[inline] - pub fn base(&self) -> &Urn { 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) -> &Urn { 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() } diff --git a/yazi-shared/src/loc/loc.rs b/yazi-shared/src/loc/loc.rs index 11b91992..58f2e357 100644 --- a/yazi-shared/src/loc/loc.rs +++ b/yazi-shared/src/loc/loc.rs @@ -2,7 +2,7 @@ use std::{hash::{Hash, Hasher}, ops::Deref, path::Path}; use anyhow::{Result, bail}; -use crate::{loc::LocBuf, path::{PathInner, PathLike}, url::{Uri, Urn}}; +use crate::{loc::LocBuf, path::{PathInner, PathLike}}; #[derive(Debug)] pub struct Loc<'a, P: ?Sized + PathLike = Path> { @@ -169,34 +169,34 @@ where pub fn as_path(self) -> &'a P { self.inner } #[inline] - pub fn uri(self) -> &'a Uri

{ - Uri::new(unsafe { + pub fn uri(self) -> &'a P { + unsafe { P::from_encoded_bytes(self.inner.encoded_bytes().get_unchecked(self.inner.len() - self.uri..)) - }) + } } #[inline] - pub fn urn(self) -> &'a Urn

{ - Urn::new(unsafe { + pub fn urn(self) -> &'a P { + unsafe { P::from_encoded_bytes(self.inner.encoded_bytes().get_unchecked(self.inner.len() - self.urn..)) - }) + } } #[inline] - pub fn base(self) -> &'a Urn

{ - Urn::new(unsafe { + pub fn base(self) -> &'a P { + unsafe { P::from_encoded_bytes(self.inner.encoded_bytes().get_unchecked(..self.inner.len() - self.uri)) - }) + } } #[inline] pub fn has_base(self) -> bool { self.inner.len() != self.uri } #[inline] - pub fn trail(self) -> &'a Urn

{ - Urn::new(unsafe { + pub fn trail(self) -> &'a P { + unsafe { P::from_encoded_bytes(self.inner.encoded_bytes().get_unchecked(..self.inner.len() - self.urn)) - }) + } } #[inline] diff --git a/yazi-shared/src/path/traits.rs b/yazi-shared/src/path/traits.rs index 3e7dc6c7..b8750137 100644 --- a/yazi-shared/src/path/traits.rs +++ b/yazi-shared/src/path/traits.rs @@ -1,5 +1,9 @@ use std::{ffi::{OsStr, OsString}, path::{Path, PathBuf}}; +pub trait AsPath { + fn as_path(&self) -> &(impl ?Sized + PathLike); +} + pub trait PathLike: AsRef { type Inner: ?Sized + PathInner; type Owned: PathBufLike + Into; @@ -21,6 +25,11 @@ pub trait PathLike: AsRef { 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; @@ -58,6 +67,22 @@ pub trait PathInner { fn encoded_bytes(&self) -> &[u8]; } +impl AsPath for &OsStr { + fn as_path(&self) -> &(impl ?Sized + PathLike) { Path::new(self) } +} + +impl AsPath for &Path { + fn as_path(&self) -> &(impl ?Sized + PathLike) { *self } +} + +impl AsPath for PathBuf { + fn as_path(&self) -> &(impl ?Sized + PathLike) { self.as_path() } +} + +impl AsPath for &PathBuf { + fn as_path(&self) -> &(impl ?Sized + PathLike) { (*self).as_path() } +} + impl PathLike for Path { type Components<'a> = std::path::Components<'a>; type Inner = OsStr; diff --git a/yazi-shared/src/url/buf.rs b/yazi-shared/src/url/buf.rs index 69ca532c..204313df 100644 --- a/yazi-shared/src/url/buf.rs +++ b/yazi-shared/src/url/buf.rs @@ -146,7 +146,7 @@ impl UrlBuf { pub fn is_internal(&self) -> bool { match self.scheme { Scheme::Regular | Scheme::Sftp(_) => true, - Scheme::Search(_) => !self.loc.uri().is_empty(), + Scheme::Search(_) => !self.loc.uri().as_os_str().is_empty(), Scheme::Archive(_) => false, } } diff --git a/yazi-shared/src/url/encode.rs b/yazi-shared/src/url/encode.rs index 86fbfeb7..3e578404 100644 --- a/yazi-shared/src/url/encode.rs +++ b/yazi-shared/src/url/encode.rs @@ -25,8 +25,8 @@ impl<'a> Encode<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { macro_rules! w { ($default_uri:expr, $default_urn:expr) => {{ - let uri = self.0.0.loc.uri().count(); - let urn = self.0.0.loc.urn().count(); + let uri = self.0.0.loc.uri().components().count(); + let urn = self.0.0.loc.urn().components().count(); match (uri != $default_uri, urn != $default_urn) { (true, true) => write!(f, ":{uri}:{urn}"), (true, false) => write!(f, ":{uri}"), diff --git a/yazi-shared/src/url/mod.rs b/yazi-shared/src/url/mod.rs index 53dbec67..c94d033a 100644 --- a/yazi-shared/src/url/mod.rs +++ b/yazi-shared/src/url/mod.rs @@ -1 +1 @@ -yazi_macro::mod_flat!(buf component cov cow display encode traits uri url urn); +yazi_macro::mod_flat!(buf component cov cow display encode traits url); diff --git a/yazi-shared/src/url/traits.rs b/yazi-shared/src/url/traits.rs index 2e0ad99c..0f8a2937 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, Uri, Url, UrlBuf, UrlCow, Urn}}; +use crate::{scheme::{AsScheme, SchemeRef}, url::{Components, Display, Url, UrlBuf, UrlCow}}; // --- AsUrl pub trait AsUrl { @@ -107,7 +107,7 @@ where fn os_str(&self) -> Cow<'_, OsStr> { self.components().os_str() } - fn pair(&self) -> Option<(Url<'_>, &Urn)> { self.as_url().pair() } + fn pair(&self) -> Option<(Url<'_>, &Path)> { self.as_url().pair() } fn parent(&self) -> Option> { self.as_url().parent() } @@ -115,11 +115,11 @@ where fn stem(&self) -> Option<&OsStr> { self.as_url().stem() } - fn strip_prefix(&self, base: impl AsUrl) -> Option<&Urn> { self.as_url().strip_prefix(base) } + fn strip_prefix(&self, base: impl AsUrl) -> Option<&Path> { self.as_url().strip_prefix(base) } - fn uri(&self) -> &Uri { self.as_url().uri() } + fn uri(&self) -> &Path { self.as_url().uri() } - fn urn(&self) -> &Urn { self.as_url().urn() } + fn urn(&self) -> &Path { self.as_url().urn() } } impl UrlLike for UrlBuf {} diff --git a/yazi-shared/src/url/uri.rs b/yazi-shared/src/url/uri.rs deleted file mode 100644 index 91402a9b..00000000 --- a/yazi-shared/src/url/uri.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::{ops::Deref, path::Path}; - -use crate::path::PathLike; - -#[derive(Debug, Eq, PartialEq, Hash)] -#[repr(transparent)] -pub struct Uri(P); - -impl

Uri

-where - P: ?Sized + PathLike, -{ - #[inline] - pub fn new + ?Sized>(p: &T) -> &Self { - unsafe { &*(p.as_ref() as *const P as *const Self) } - } - - #[inline] - pub fn count(&self) -> usize { self.0.components().count() } - - #[inline] - pub fn is_empty(&self) -> bool { self.0.len() == 0 } -} - -impl

Deref for Uri

-where - P: ?Sized + PathLike, -{ - type Target = P; - - fn deref(&self) -> &Self::Target { &self.0 } -} - -impl

AsRef

for Uri

-where - P: ?Sized + PathLike, -{ - fn as_ref(&self) -> &P { &self.0 } -} diff --git a/yazi-shared/src/url/url.rs b/yazi-shared/src/url/url.rs index 6dc8f6d9..b71ce3c4 100644 --- a/yazi-shared/src/url/url.rs +++ b/yazi-shared/src/url/url.rs @@ -2,7 +2,7 @@ use std::{borrow::Cow, ffi::OsStr, fmt::{Debug, Formatter}, path::Path}; use hashbrown::Equivalent; -use crate::{loc::{Loc, LocBuf}, scheme::SchemeRef, url::{AsUrl, Components, Encode, Uri, UrlBuf, Urn}}; +use crate::{loc::{Loc, LocBuf}, scheme::SchemeRef, url::{AsUrl, Components, Encode, UrlBuf}}; #[derive(Clone, Copy, Eq, Hash, PartialEq)] pub struct Url<'a> { @@ -79,13 +79,13 @@ impl<'a> Url<'a> { UrlBuf { loc, scheme: self.scheme.into() } } - pub fn strip_prefix(self, base: impl AsUrl) -> Option<&'a Urn> { + pub fn strip_prefix(self, base: impl AsUrl) -> Option<&'a Path> { use SchemeRef as S; let base = base.as_url(); let prefix = self.loc.strip_prefix(base.loc)?; - Some(Urn::new(match (self.scheme, base.scheme) { + Some(match (self.scheme, base.scheme) { // Same scheme (S::Regular, S::Regular) => Some(prefix), (S::Search(_), S::Search(_)) => Some(prefix), @@ -97,10 +97,10 @@ impl<'a> Url<'a> { (S::Search(_), S::Regular) => Some(prefix), // Only the entry of archives is a local file - (S::Regular, S::Archive(_)) => Some(prefix).filter(|_| base.uri().is_empty()), - (S::Search(_), S::Archive(_)) => Some(prefix).filter(|_| base.uri().is_empty()), - (S::Archive(_), S::Regular) => Some(prefix).filter(|_| self.uri().is_empty()), - (S::Archive(_), S::Search(_)) => Some(prefix).filter(|_| self.uri().is_empty()), + (S::Regular, S::Archive(_)) => Some(prefix).filter(|_| base.uri().as_os_str().is_empty()), + (S::Search(_), S::Archive(_)) => Some(prefix).filter(|_| base.uri().as_os_str().is_empty()), + (S::Archive(_), S::Regular) => Some(prefix).filter(|_| self.uri().as_os_str().is_empty()), + (S::Archive(_), S::Search(_)) => Some(prefix).filter(|_| self.uri().as_os_str().is_empty()), // Independent virtual file space (S::Regular, S::Sftp(_)) => None, @@ -109,14 +109,14 @@ impl<'a> Url<'a> { (S::Sftp(_), S::Regular) => None, (S::Sftp(_), S::Search(_)) => None, (S::Sftp(_), S::Archive(_)) => None, - }?)) + }?) } #[inline] - pub fn uri(self) -> &'a Uri { self.loc.uri() } + pub fn uri(self) -> &'a Path { self.loc.uri() } #[inline] - pub fn urn(self) -> &'a Urn { self.loc.urn() } + pub fn urn(self) -> &'a Path { self.loc.urn() } #[inline] pub fn name(self) -> Option<&'a OsStr> { self.loc.name() } @@ -154,13 +154,17 @@ impl<'a> Url<'a> { S::Regular => Self { loc: parent.into(), scheme: S::Regular }, // Search - S::Search(_) if uri.is_empty() => Self { loc: parent.into(), scheme: S::Regular }, + S::Search(_) if uri.as_os_str().is_empty() => { + Self { loc: parent.into(), scheme: S::Regular } + } S::Search(_) => { Self { loc: Loc::new(parent, self.loc.base(), self.loc.base()), scheme: self.scheme } } // Archive - S::Archive(_) if uri.is_empty() => Self { loc: parent.into(), scheme: S::Regular }, + S::Archive(_) if uri.as_os_str().is_empty() => { + Self { loc: parent.into(), scheme: S::Regular } + } S::Archive(_) if uri.components().nth(1).is_none() => { Self { loc: Loc::zeroed(parent), scheme: self.scheme } } @@ -196,7 +200,7 @@ impl<'a> Url<'a> { } #[inline] - pub fn pair(self) -> Option<(Self, &'a Urn)> { Some((self.parent()?, self.loc.urn())) } + pub fn pair(self) -> Option<(Self, &'a Path)> { Some((self.parent()?, self.loc.urn())) } #[inline] pub fn as_path(self) -> Option<&'a Path> { diff --git a/yazi-shared/src/url/urn.rs b/yazi-shared/src/url/urn.rs deleted file mode 100644 index fff741f7..00000000 --- a/yazi-shared/src/url/urn.rs +++ /dev/null @@ -1,124 +0,0 @@ -use std::{borrow::Borrow, ops::Deref, path::{Path, PathBuf}}; - -use serde::Serialize; - -use crate::path::{PathBufLike, PathLike}; - -#[derive(Debug, Eq, PartialEq, Hash)] -#[repr(transparent)] -pub struct Urn(P); - -impl

Urn

-where - P: ?Sized + PathLike, -{ - #[inline] - pub fn new + ?Sized>(p: &T) -> &Self { - unsafe { &*(p.as_ref() as *const P as *const Self) } - } - - #[inline] - pub fn name(&self) -> Option<&P::Inner> { self.0.file_name() } - - #[inline] - pub fn count(&self) -> usize { self.0.components().count() } - - #[inline] - pub fn encoded_bytes(&self) -> &[u8] { self.0.encoded_bytes() } - - #[cfg(unix)] - #[inline] - pub fn is_hidden(&self) -> bool { - use crate::path::PathInner; - self.name().is_some_and(|s| s.encoded_bytes().starts_with(b".")) - } -} - -impl

Deref for Urn

-where - P: ?Sized + PathLike, -{ - type Target = P; - - fn deref(&self) -> &Self::Target { &self.0 } -} - -impl

AsRef

for Urn

-where - P: ?Sized + PathLike, -{ - fn as_ref(&self) -> &P { &self.0 } -} - -impl

From<&Urn

> for PathBuf -where - P: ?Sized + PathLike + ToOwned, -{ - fn from(value: &Urn

) -> Self { value.0.to_owned() } -} - -impl

ToOwned for Urn

-where - P: ?Sized + PathLike + ToOwned::Owned>, - UrnBuf<

::Owned>: Borrow>, -{ - type Owned = UrnBuf<

::Owned>; - - fn to_owned(&self) -> Self::Owned { UrnBuf(self.0.to_owned()) } -} - -impl

PartialEq> for &Urn

-where - P: ?Sized + PathLike + PartialEq, -{ - fn eq(&self, other: &UrnBuf) -> bool { self.0 == other.0 } -} - -// --- UrnBuf -#[derive(Clone, Debug, Default, Eq, Hash, PartialEq, Serialize)] -pub struct UrnBuf(P); - -impl

Borrow> for UrnBuf

-where - P: PathBufLike, -{ - fn borrow(&self) -> &Urn { Urn::new(&self.0) } -} - -impl

Deref for UrnBuf

-where - P: PathBufLike, -{ - type Target = Urn; - - fn deref(&self) -> &Self::Target { Urn::new(&self.0) } -} - -impl

AsRef for UrnBuf

-where - P: PathBufLike, -{ - fn as_ref(&self) -> &P::Borrowed { Urn::new(&self.0) } -} - -impl

PartialEq> for UrnBuf

-where - P: PathBufLike + PartialEq, -{ - fn eq(&self, other: &Urn) -> bool { self.0 == other.0 } -} - -impl From for UrnBuf -where - T: Into, -{ - fn from(value: T) -> Self { Self(value.into()) } -} - -impl

UrnBuf

-where - P: PathBufLike, -{ - #[inline] - pub fn as_urn(&self) -> &Urn { self } -}