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 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
#[derive(Clone, Debug, Eq)]
@ -138,14 +138,10 @@ impl PathBufDyn {
where
T: AsStrand,
{
Ok(match (self, name.as_strand()) {
(Self::Os(p), Strand::Os(s)) => p.set_file_name(s),
(Self::Os(p), Strand::Utf8(s)) => p.set_file_name(s),
(Self::Os(p), Strand::Bytes(b)) => {
p.set_file_name(OsStr::from_wtf8(b).map_err(|_| SetNameError::FromWtf8)?)
}
(Self::Unix(p), s) => p.set_file_name(s.encoded_bytes()),
let s = name.as_strand();
Ok(match self {
Self::Os(p) => p.set_file_name(s.as_os()?),
Self::Unix(p) => p.set_file_name(s.encoded_bytes()),
})
}

View file

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

View file

@ -4,7 +4,7 @@ use anyhow::Result;
use hashbrown::Equivalent;
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)]
pub enum PathDyn<'p> {
@ -186,14 +186,10 @@ impl<'p> PathDyn<'p> {
where
T: AsStrand,
{
Ok(match (self, child.as_strand()) {
(Self::Os(p), Strand::Os(q)) => p.ends_with(q),
(Self::Os(p), Strand::Utf8(q)) => p.ends_with(q),
(Self::Os(p), Strand::Bytes(b)) => {
p.ends_with(OsStr::from_wtf8(b).map_err(|_| EndsWithError)?)
}
(Self::Unix(p), s) => p.ends_with(s.encoded_bytes()),
let s = child.as_strand();
Ok(match self {
Self::Os(p) => p.ends_with(s.as_os()?),
Self::Unix(p) => p.ends_with(s.encoded_bytes()),
})
}
@ -201,14 +197,10 @@ impl<'p> PathDyn<'p> {
where
T: AsStrand,
{
Ok(match (self, path.as_strand()) {
(Self::Os(p), Strand::Os(q)) => PathBufDyn::Os(p.join(q)),
(Self::Os(p), Strand::Utf8(q)) => PathBufDyn::Os(p.join(q)),
(Self::Os(p), Strand::Bytes(b)) => {
PathBufDyn::Os(p.join(OsStr::from_wtf8(b).map_err(|_| JoinError::FromWtf8)?))
}
(Self::Unix(p), s) => PathBufDyn::Unix(p.join(s.encoded_bytes())),
let s = path.as_strand();
Ok(match self {
Self::Os(p) => PathBufDyn::Os(p.join(s.as_os()?)),
Self::Unix(p) => PathBufDyn::Unix(p.join(s.encoded_bytes())),
})
}
@ -235,14 +227,10 @@ impl<'p> PathDyn<'p> {
where
T: AsStrand,
{
Ok(match (self, base.as_strand()) {
(Self::Os(p), Strand::Os(s)) => p.starts_with(s),
(Self::Os(p), Strand::Utf8(s)) => p.starts_with(s),
(Self::Os(p), Strand::Bytes(b)) => {
p.starts_with(OsStr::from_wtf8(b).map_err(|_| StartsWithError)?)
}
(Self::Unix(p), s) => p.starts_with(s.encoded_bytes()),
let s = base.as_strand();
Ok(match self {
Self::Os(p) => p.starts_with(s.as_os()?),
Self::Unix(p) => p.starts_with(s.encoded_bytes()),
})
}
@ -250,14 +238,10 @@ impl<'p> PathDyn<'p> {
where
T: AsStrand,
{
Ok(match (self, base.as_strand()) {
(Self::Os(p), Strand::Os(s)) => Self::Os(p.strip_prefix(s)?),
(Self::Os(p), Strand::Utf8(s)) => Self::Os(p.strip_prefix(s)?),
(Self::Os(p), Strand::Bytes(b)) => {
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())?),
let s = base.as_strand();
Ok(match self {
Self::Os(p) => Self::Os(p.strip_prefix(s.as_os()?)?),
Self::Unix(p) => 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() }
}
impl AsStrand for Cow<'_, [u8]> {
fn as_strand(&self) -> Strand<'_> { Strand::Bytes(self) }
}
impl AsStrand for Cow<'_, OsStr> {
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 yazi_shared::{scheme::SchemeKind, url::{AsUrl, Url, UrlBuf, UrlCow, UrlLike}};
@ -44,7 +47,8 @@ impl Reporter {
// Virtual caches
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(dir).ok();