This commit is contained in:
Stephan Hradek 2025-11-28 09:17:35 +01:00
commit 0337fe8379
No known key found for this signature in database
GPG key ID: DDF026DB9AE9A387
5 changed files with 47 additions and 48 deletions

View file

@ -1,8 +1,8 @@
use std::{ffi::{OsStr, OsString}, hash::{Hash, Hasher}}; use std::{ffi::OsString, hash::{Hash, Hasher}};
use hashbrown::Equivalent; use hashbrown::Equivalent;
use crate::{path::{AsPath, Component, PathDyn, PathDynError, PathKind, SetNameError}, strand::{AsStrand, Strand}, wtf8::{FromWtf8, FromWtf8Vec}}; use crate::{path::{AsPath, Component, PathDyn, PathDynError, PathKind, SetNameError}, strand::AsStrand, wtf8::FromWtf8Vec};
// --- PathBufDyn // --- PathBufDyn
#[derive(Clone, Debug, Eq)] #[derive(Clone, Debug, Eq)]
@ -138,14 +138,10 @@ impl PathBufDyn {
where where
T: AsStrand, T: AsStrand,
{ {
Ok(match (self, name.as_strand()) { let s = name.as_strand();
(Self::Os(p), Strand::Os(s)) => p.set_file_name(s), Ok(match self {
(Self::Os(p), Strand::Utf8(s)) => p.set_file_name(s), Self::Os(p) => p.set_file_name(s.as_os()?),
(Self::Os(p), Strand::Bytes(b)) => { Self::Unix(p) => p.set_file_name(s.encoded_bytes()),
p.set_file_name(OsStr::from_wtf8(b).map_err(|_| SetNameError::FromWtf8)?)
}
(Self::Unix(p), s) => p.set_file_name(s.encoded_bytes()),
}) })
} }

View file

@ -5,13 +5,15 @@ use crate::strand::StrandError;
// --- EndsWithError // --- EndsWithError
#[derive(Debug, Error)] #[derive(Debug, Error)]
#[error("calling ends_with on paths with different encodings")] #[error("calling ends_with on paths with different encodings")]
pub struct EndsWithError; pub enum EndsWithError {
FromStrand(#[from] StrandError),
}
// --- JoinError // --- JoinError
#[derive(Debug, Error)] #[derive(Debug, Error)]
#[error("calling join on paths with different encodings")] #[error("calling join on paths with different encodings")]
pub enum JoinError { pub enum JoinError {
FromWtf8, FromStrand(#[from] StrandError),
FromPathDyn(#[from] PathDynError), FromPathDyn(#[from] PathDynError),
} }
@ -47,7 +49,6 @@ impl From<PathDynError> for std::io::Error {
#[derive(Debug, Error)] #[derive(Debug, Error)]
#[error("calling set_name on paths with different encodings")] #[error("calling set_name on paths with different encodings")]
pub enum SetNameError { pub enum SetNameError {
FromWtf8,
FromStrand(#[from] StrandError), FromStrand(#[from] StrandError),
} }
@ -79,7 +80,9 @@ impl From<StrandError> for RsplitOnceError {
// --- StartsWithError // --- StartsWithError
#[derive(Error, Debug)] #[derive(Error, Debug)]
#[error("calling starts_with on paths with different encodings")] #[error("calling starts_with on paths with different encodings")]
pub struct StartsWithError; pub enum StartsWithError {
FromStrand(#[from] StrandError),
}
// --- StripPrefixError // --- StripPrefixError
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -92,6 +95,14 @@ pub enum StripPrefixError {
WrongEncoding, WrongEncoding,
} }
impl From<StrandError> for StripPrefixError {
fn from(err: StrandError) -> Self {
match err {
StrandError::AsOs | StrandError::AsUtf8 => Self::WrongEncoding,
}
}
}
impl From<std::path::StripPrefixError> for StripPrefixError { impl From<std::path::StripPrefixError> for StripPrefixError {
fn from(_: std::path::StripPrefixError) -> Self { Self::NotPrefix } fn from(_: std::path::StripPrefixError) -> Self { Self::NotPrefix }
} }

View file

@ -4,7 +4,7 @@ use anyhow::Result;
use hashbrown::Equivalent; use hashbrown::Equivalent;
use super::{RsplitOnceError, StartsWithError}; use super::{RsplitOnceError, StartsWithError};
use crate::{BytesExt, Utf8BytePredictor, path::{AsPath, Components, Display, EndsWithError, JoinError, PathBufDyn, PathDynError, PathKind, StripPrefixError}, strand::{AsStrand, Strand, StrandError}, wtf8::FromWtf8}; use crate::{BytesExt, Utf8BytePredictor, path::{AsPath, Components, Display, EndsWithError, JoinError, PathBufDyn, PathDynError, PathKind, StripPrefixError}, strand::{AsStrand, Strand, StrandError}};
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum PathDyn<'p> { pub enum PathDyn<'p> {
@ -186,14 +186,10 @@ impl<'p> PathDyn<'p> {
where where
T: AsStrand, T: AsStrand,
{ {
Ok(match (self, child.as_strand()) { let s = child.as_strand();
(Self::Os(p), Strand::Os(q)) => p.ends_with(q), Ok(match self {
(Self::Os(p), Strand::Utf8(q)) => p.ends_with(q), Self::Os(p) => p.ends_with(s.as_os()?),
(Self::Os(p), Strand::Bytes(b)) => { Self::Unix(p) => p.ends_with(s.encoded_bytes()),
p.ends_with(OsStr::from_wtf8(b).map_err(|_| EndsWithError)?)
}
(Self::Unix(p), s) => p.ends_with(s.encoded_bytes()),
}) })
} }
@ -201,14 +197,10 @@ impl<'p> PathDyn<'p> {
where where
T: AsStrand, T: AsStrand,
{ {
Ok(match (self, path.as_strand()) { let s = path.as_strand();
(Self::Os(p), Strand::Os(q)) => PathBufDyn::Os(p.join(q)), Ok(match self {
(Self::Os(p), Strand::Utf8(q)) => PathBufDyn::Os(p.join(q)), Self::Os(p) => PathBufDyn::Os(p.join(s.as_os()?)),
(Self::Os(p), Strand::Bytes(b)) => { Self::Unix(p) => PathBufDyn::Unix(p.join(s.encoded_bytes())),
PathBufDyn::Os(p.join(OsStr::from_wtf8(b).map_err(|_| JoinError::FromWtf8)?))
}
(Self::Unix(p), s) => PathBufDyn::Unix(p.join(s.encoded_bytes())),
}) })
} }
@ -235,14 +227,10 @@ impl<'p> PathDyn<'p> {
where where
T: AsStrand, T: AsStrand,
{ {
Ok(match (self, base.as_strand()) { let s = base.as_strand();
(Self::Os(p), Strand::Os(s)) => p.starts_with(s), Ok(match self {
(Self::Os(p), Strand::Utf8(s)) => p.starts_with(s), Self::Os(p) => p.starts_with(s.as_os()?),
(Self::Os(p), Strand::Bytes(b)) => { Self::Unix(p) => p.starts_with(s.encoded_bytes()),
p.starts_with(OsStr::from_wtf8(b).map_err(|_| StartsWithError)?)
}
(Self::Unix(p), s) => p.starts_with(s.encoded_bytes()),
}) })
} }
@ -250,14 +238,10 @@ impl<'p> PathDyn<'p> {
where where
T: AsStrand, T: AsStrand,
{ {
Ok(match (self, base.as_strand()) { let s = base.as_strand();
(Self::Os(p), Strand::Os(s)) => Self::Os(p.strip_prefix(s)?), Ok(match self {
(Self::Os(p), Strand::Utf8(s)) => Self::Os(p.strip_prefix(s)?), Self::Os(p) => Self::Os(p.strip_prefix(s.as_os()?)?),
(Self::Os(p), Strand::Bytes(b)) => { Self::Unix(p) => Self::Unix(p.strip_prefix(s.encoded_bytes())?),
Self::Os(p.strip_prefix(OsStr::from_wtf8(b).map_err(|_| StripPrefixError::WrongEncoding)?)?)
}
(Self::Unix(p), s) => Self::Unix(p.strip_prefix(s.encoded_bytes())?),
}) })
} }

View file

@ -59,6 +59,10 @@ impl AsStrand for crate::path::Components<'_> {
fn as_strand(&self) -> Strand<'_> { self.strand() } fn as_strand(&self) -> Strand<'_> { self.strand() }
} }
impl AsStrand for Cow<'_, [u8]> {
fn as_strand(&self) -> Strand<'_> { Strand::Bytes(self) }
}
impl AsStrand for Cow<'_, OsStr> { impl AsStrand for Cow<'_, OsStr> {
fn as_strand(&self) -> Strand<'_> { Strand::Os(self) } fn as_strand(&self) -> Strand<'_> { Strand::Os(self) }
} }

View file

@ -1,3 +1,6 @@
use std::borrow::Cow;
use percent_encoding::percent_decode;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use yazi_shared::{scheme::SchemeKind, url::{AsUrl, Url, UrlBuf, UrlCow, UrlLike}}; use yazi_shared::{scheme::SchemeKind, url::{AsUrl, Url, UrlBuf, UrlCow, UrlLike}};
@ -44,7 +47,8 @@ impl Reporter {
// Virtual caches // Virtual caches
let Some(dir) = watched.find_by_cache(parent.loc()) else { continue }; let Some(dir) = watched.find_by_cache(parent.loc()) else { continue };
if let Some(Ok(u)) = url.name().map(|n| dir.try_join(n)) { let Some(name) = url.name() else { continue };
if let Ok(u) = dir.try_join(Cow::from(percent_decode(name.encoded_bytes()))) {
self.remote_tx.send(u).ok(); self.remote_tx.send(u).ok();
} }
self.remote_tx.send(dir).ok(); self.remote_tx.send(dir).ok();