mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
refactor: simplify paths (#3297)
This commit is contained in:
parent
b766cff69f
commit
604b86612a
30 changed files with 180 additions and 317 deletions
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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<Url>;
|
||||
|
||||
|
|
@ -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::<std::path::PathBuf>::new(me.urn()))
|
||||
});
|
||||
cached_field!(fields, base, |_, me| Ok(me.base().map(Self::new)));
|
||||
|
||||
cached_field!(fields, scheme, |_, me| Ok(Scheme::new(&me.scheme)));
|
||||
|
|
|
|||
|
|
@ -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<P: PathBufLike = PathBuf> {
|
||||
inner: yazi_shared::url::UrnBuf<P>,
|
||||
}
|
||||
pub struct Path<P: PathBufLike = PathBuf>(pub P);
|
||||
|
||||
impl<P> Deref for Urn<P>
|
||||
impl<P> Deref for Path<P>
|
||||
where
|
||||
P: PathBufLike,
|
||||
{
|
||||
type Target = yazi_shared::url::UrnBuf<P>;
|
||||
type Target = P;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
}
|
||||
|
||||
impl<P> From<Urn<P>> for yazi_shared::url::UrnBuf<P>
|
||||
impl<P> Path<P>
|
||||
where
|
||||
P: PathBufLike,
|
||||
{
|
||||
fn from(value: Urn<P>) -> Self { value.inner }
|
||||
pub fn new(urn: impl Into<P>) -> Self { Self(urn.into()) }
|
||||
}
|
||||
|
||||
impl<P> Urn<P>
|
||||
where
|
||||
P: PathBufLike,
|
||||
{
|
||||
pub fn new(urn: impl Into<yazi_shared::url::UrnBuf<P>>) -> Self { Self { inner: urn.into() } }
|
||||
}
|
||||
|
||||
impl<P> FromLua for Urn<P>
|
||||
impl<P> FromLua for Path<P>
|
||||
where
|
||||
P: PathBufLike,
|
||||
{
|
||||
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
|
||||
Ok(match value {
|
||||
Value::UserData(ud) => ud.take()?,
|
||||
_ => Err("Expected a Urn".into_lua_err())?,
|
||||
_ => Err("Expected a Path".into_lua_err())?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<P> UserData for Urn<P> where P: PathBufLike {}
|
||||
impl<P> UserData for Path<P> where P: PathBufLike {}
|
||||
|
|
|
|||
|
|
@ -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<UrlBuf>,
|
||||
pub files: Vec<UrnBuf>,
|
||||
pub files: Vec<PathBuf>,
|
||||
|
||||
pub local_events: HashSet<String>,
|
||||
pub remote_events: HashSet<String>,
|
||||
|
|
@ -22,25 +22,25 @@ pub struct Boot {
|
|||
}
|
||||
|
||||
impl Boot {
|
||||
async fn parse_entries(entries: &[UrlBuf]) -> (Vec<UrlBuf>, Vec<UrnBuf>) {
|
||||
async fn parse_entries(entries: &[UrlBuf]) -> (Vec<UrlBuf>, Vec<PathBuf>) {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<UrnBuf, u8>,
|
||||
pub matched: HashMap<PathBuf, u8>,
|
||||
lock: FinderLock,
|
||||
}
|
||||
|
||||
|
|
@ -76,7 +78,7 @@ impl Finder {
|
|||
}
|
||||
|
||||
impl Finder {
|
||||
pub fn matched_idx(&self, folder: &Folder, urn: &Urn) -> Option<u8> {
|
||||
pub fn matched_idx(&self, folder: &Folder, urn: &Path) -> Option<u8> {
|
||||
if self.lock == *folder { self.matched.get(urn).copied() } else { None }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<UrnBuf>,
|
||||
pub trace: Option<PathBuf>,
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ impl Sendable {
|
|||
Some(t) if t == TypeId::of::<yazi_binding::Url>() => {
|
||||
Data::Url(ud.take::<yazi_binding::Url>()?.into())
|
||||
}
|
||||
Some(t) if t == TypeId::of::<yazi_binding::Urn>() => {
|
||||
Data::Urn(ud.take::<yazi_binding::Urn>()?.into())
|
||||
Some(t) if t == TypeId::of::<yazi_binding::Path<std::path::PathBuf>>() => {
|
||||
Data::Path(ud.take::<yazi_binding::Path<std::path::PathBuf>>()?.0)
|
||||
}
|
||||
Some(t) if t == TypeId::of::<yazi_binding::Id>() => {
|
||||
Data::Id(**ud.borrow::<yazi_binding::Id>()?)
|
||||
|
|
@ -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::<std::path::PathBuf>::new(u).into_lua(lua)?,
|
||||
Data::Any(a) => {
|
||||
if a.is::<yazi_fs::FilesOp>() {
|
||||
lua.create_any_userdata(*a.downcast::<yazi_fs::FilesOp>().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::<std::path::PathBuf>::new(u).into_lua(lua)?,
|
||||
Data::Bytes(b) => Value::String(lua.create_string(b)?),
|
||||
Data::Any(a) => {
|
||||
if let Some(t) = a.downcast_ref::<yazi_fs::FilesOp>() {
|
||||
|
|
@ -214,8 +214,8 @@ impl Sendable {
|
|||
Some(t) if t == TypeId::of::<yazi_binding::Url>() => {
|
||||
DataKey::Url(ud.take::<yazi_binding::Url>()?.into())
|
||||
}
|
||||
Some(t) if t == TypeId::of::<yazi_binding::Urn>() => {
|
||||
DataKey::Urn(ud.take::<yazi_binding::Urn>()?.into())
|
||||
Some(t) if t == TypeId::of::<yazi_binding::Path>() => {
|
||||
DataKey::Path(ud.take::<yazi_binding::Path>()?.0)
|
||||
}
|
||||
Some(t) if t == TypeId::of::<yazi_binding::Id>() => {
|
||||
DataKey::Id(**ud.borrow::<yazi_binding::Id>()?)
|
||||
|
|
@ -230,7 +230,7 @@ impl Sendable {
|
|||
fn key_to_value(lua: &Lua, key: DataKey) -> mlua::Result<Value> {
|
||||
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::<std::path::PathBuf>::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::<std::path::PathBuf>::new(u).into_lua(lua)?,
|
||||
DataKey::Bytes(b) => Value::String(lua.create_string(b)?),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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() }
|
||||
|
|
|
|||
|
|
@ -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<UrnBuf, u64>,
|
||||
pub sizes: HashMap<PathBuf, u64>,
|
||||
|
||||
sorter: FilesSorter,
|
||||
filter: Option<Filter>,
|
||||
|
|
@ -69,7 +69,7 @@ impl Files {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update_size(&mut self, mut sizes: HashMap<UrnBuf, u64>) {
|
||||
pub fn update_size(&mut self, mut sizes: HashMap<PathBuf, u64>) {
|
||||
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<UrnBuf>) -> Vec<usize> {
|
||||
pub fn update_deleting(&mut self, urns: HashSet<PathBuf>) -> Vec<usize> {
|
||||
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<UrnBuf>) -> Vec<usize> {
|
||||
pub fn update_deleting(&mut self, mut urns: HashSet<PathBuf>) -> Vec<usize> {
|
||||
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<UrnBuf, File>,
|
||||
) -> (HashMap<UrnBuf, File>, HashMap<UrnBuf, File>) {
|
||||
files: HashMap<PathBuf, File>,
|
||||
) -> (HashMap<PathBuf, File>, HashMap<PathBuf, File>) {
|
||||
if files.is_empty() {
|
||||
return Default::default();
|
||||
}
|
||||
|
|
@ -222,7 +221,7 @@ impl Files {
|
|||
(hidden, items)
|
||||
}
|
||||
|
||||
pub fn update_upserting(&mut self, files: HashMap<UrnBuf, File>) {
|
||||
pub fn update_upserting(&mut self, files: HashMap<PathBuf, File>) {
|
||||
if files.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
|
@ -271,7 +270,7 @@ impl Files {
|
|||
impl Files {
|
||||
// --- Items
|
||||
#[inline]
|
||||
pub fn position(&self, urn: &Urn) -> Option<usize> { self.iter().position(|f| urn == f.urn()) }
|
||||
pub fn position(&self, urn: &Path) -> Option<usize> { self.iter().position(|f| urn == f.urn()) }
|
||||
|
||||
// --- Ticket
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -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<T>(&self, name: T) -> bool
|
||||
where
|
||||
T: AsPath,
|
||||
{
|
||||
self.regex.is_match(name.as_path().encoded_bytes())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn highlighted(&self, name: impl AsRef<OsStr>) -> Option<Vec<Range<usize>>> {
|
||||
|
|
@ -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() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<File>, Cha),
|
||||
Part(UrlBuf, Vec<File>, Id),
|
||||
Done(UrlBuf, Cha, Id),
|
||||
Size(UrlBuf, HashMap<UrnBuf, u64>),
|
||||
Size(UrlBuf, HashMap<PathBuf, u64>),
|
||||
IOErr(UrlBuf, Error),
|
||||
|
||||
Creating(UrlBuf, Vec<File>),
|
||||
Deleting(UrlBuf, HashSet<UrnBuf>),
|
||||
Updating(UrlBuf, HashMap<UrnBuf, File>),
|
||||
Upserting(UrlBuf, HashMap<UrnBuf, File>),
|
||||
Deleting(UrlBuf, HashSet<PathBuf>),
|
||||
Updating(UrlBuf, HashMap<PathBuf, File>),
|
||||
Upserting(UrlBuf, HashMap<PathBuf, File>),
|
||||
}
|
||||
|
||||
impl FilesOp {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,11 @@ use yazi_shared::{loc::LocBuf, url::{UrlBuf, UrlCow}};
|
|||
|
||||
pub fn clean_url<'a>(url: impl Into<UrlCow<'a>>) -> 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() }
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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<UrnBuf, u64>) {
|
||||
pub(super) fn sort(&self, items: &mut [File], sizes: &HashMap<PathBuf, u64>) {
|
||||
if items.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<CmpItem>,
|
||||
pub cache_name: UrlBuf,
|
||||
pub word: UrnBuf,
|
||||
pub word: PathBuf,
|
||||
pub ticket: Id,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<UrnBuf>,
|
||||
pub urn: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl From<Option<UrnBuf>> for HoverOpt {
|
||||
fn from(urn: Option<UrnBuf>) -> Self { Self { urn } }
|
||||
impl From<Option<PathBuf>> for HoverOpt {
|
||||
fn from(urn: Option<PathBuf>) -> Self { Self { urn } }
|
||||
}
|
||||
|
||||
impl FromLua for HoverOpt {
|
||||
|
|
|
|||
|
|
@ -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::<Urn, u64>()
|
||||
.map(|r| r.map(|(urn, size)| (urn.into(), size)))
|
||||
.pairs::<Path, u64>()
|
||||
.map(|r| r.map(|(urn, size)| (urn.0, size)))
|
||||
.collect::<mlua::Result<_>>()?,
|
||||
)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<u8>),
|
||||
#[serde(skip)]
|
||||
|
|
|
|||
|
|
@ -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<u8>),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<P: PathBufLike = PathBuf> {
|
||||
|
|
@ -215,19 +215,19 @@ where
|
|||
P: PathBufLike,
|
||||
{
|
||||
#[inline]
|
||||
pub fn uri(&self) -> &Uri<P::Borrowed> { self.as_loc().uri() }
|
||||
pub fn uri(&self) -> &P::Borrowed { self.as_loc().uri() }
|
||||
|
||||
#[inline]
|
||||
pub fn urn(&self) -> &Urn<P::Borrowed> { self.as_loc().urn() }
|
||||
pub fn urn(&self) -> &P::Borrowed { self.as_loc().urn() }
|
||||
|
||||
#[inline]
|
||||
pub fn base(&self) -> &Urn<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) -> &Urn<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() }
|
||||
|
|
|
|||
|
|
@ -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<P> {
|
||||
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<P> {
|
||||
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<P> {
|
||||
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<P> {
|
||||
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]
|
||||
|
|
|
|||
|
|
@ -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<Self> {
|
||||
type Inner: ?Sized + PathInner;
|
||||
type Owned: PathBufLike + Into<Self::Owned>;
|
||||
|
|
@ -21,6 +25,11 @@ pub trait PathLike: AsRef<Self> {
|
|||
|
||||
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<T>(&self, base: T) -> Self::Owned
|
||||
where
|
||||
T: AsRef<Self>;
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}"),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<Url<'_>> { 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 {}
|
||||
|
|
|
|||
|
|
@ -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: ?Sized + PathLike = Path>(P);
|
||||
|
||||
impl<P> Uri<P>
|
||||
where
|
||||
P: ?Sized + PathLike,
|
||||
{
|
||||
#[inline]
|
||||
pub fn new<T: AsRef<P> + ?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<P> Deref for Uri<P>
|
||||
where
|
||||
P: ?Sized + PathLike,
|
||||
{
|
||||
type Target = P;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
}
|
||||
|
||||
impl<P> AsRef<P> for Uri<P>
|
||||
where
|
||||
P: ?Sized + PathLike,
|
||||
{
|
||||
fn as_ref(&self) -> &P { &self.0 }
|
||||
}
|
||||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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: ?Sized + PathLike = Path>(P);
|
||||
|
||||
impl<P> Urn<P>
|
||||
where
|
||||
P: ?Sized + PathLike,
|
||||
{
|
||||
#[inline]
|
||||
pub fn new<T: AsRef<P> + ?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<P> Deref for Urn<P>
|
||||
where
|
||||
P: ?Sized + PathLike,
|
||||
{
|
||||
type Target = P;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
}
|
||||
|
||||
impl<P> AsRef<P> for Urn<P>
|
||||
where
|
||||
P: ?Sized + PathLike,
|
||||
{
|
||||
fn as_ref(&self) -> &P { &self.0 }
|
||||
}
|
||||
|
||||
impl<P> From<&Urn<P>> for PathBuf
|
||||
where
|
||||
P: ?Sized + PathLike + ToOwned<Owned = PathBuf>,
|
||||
{
|
||||
fn from(value: &Urn<P>) -> Self { value.0.to_owned() }
|
||||
}
|
||||
|
||||
impl<P> ToOwned for Urn<P>
|
||||
where
|
||||
P: ?Sized + PathLike + ToOwned<Owned = <P as PathLike>::Owned>,
|
||||
UrnBuf<<P as PathLike>::Owned>: Borrow<Urn<P>>,
|
||||
{
|
||||
type Owned = UrnBuf<<P as PathLike>::Owned>;
|
||||
|
||||
fn to_owned(&self) -> Self::Owned { UrnBuf(self.0.to_owned()) }
|
||||
}
|
||||
|
||||
impl<P> PartialEq<UrnBuf<P::Owned>> for &Urn<P>
|
||||
where
|
||||
P: ?Sized + PathLike + PartialEq<P::Owned>,
|
||||
{
|
||||
fn eq(&self, other: &UrnBuf<P::Owned>) -> bool { self.0 == other.0 }
|
||||
}
|
||||
|
||||
// --- UrnBuf
|
||||
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq, Serialize)]
|
||||
pub struct UrnBuf<P: PathBufLike = PathBuf>(P);
|
||||
|
||||
impl<P> Borrow<Urn<P::Borrowed>> for UrnBuf<P>
|
||||
where
|
||||
P: PathBufLike,
|
||||
{
|
||||
fn borrow(&self) -> &Urn<P::Borrowed> { Urn::new(&self.0) }
|
||||
}
|
||||
|
||||
impl<P> Deref for UrnBuf<P>
|
||||
where
|
||||
P: PathBufLike,
|
||||
{
|
||||
type Target = Urn<P::Borrowed>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { Urn::new(&self.0) }
|
||||
}
|
||||
|
||||
impl<P> AsRef<P::Borrowed> for UrnBuf<P>
|
||||
where
|
||||
P: PathBufLike,
|
||||
{
|
||||
fn as_ref(&self) -> &P::Borrowed { Urn::new(&self.0) }
|
||||
}
|
||||
|
||||
impl<P> PartialEq<Urn<P::Borrowed>> for UrnBuf<P>
|
||||
where
|
||||
P: PathBufLike + PartialEq<P::Borrowed>,
|
||||
{
|
||||
fn eq(&self, other: &Urn<P::Borrowed>) -> bool { self.0 == other.0 }
|
||||
}
|
||||
|
||||
impl<T> From<T> for UrnBuf<PathBuf>
|
||||
where
|
||||
T: Into<PathBuf>,
|
||||
{
|
||||
fn from(value: T) -> Self { Self(value.into()) }
|
||||
}
|
||||
|
||||
impl<P> UrnBuf<P>
|
||||
where
|
||||
P: PathBufLike,
|
||||
{
|
||||
#[inline]
|
||||
pub fn as_urn(&self) -> &Urn<P::Borrowed> { self }
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue