fix: always follow symlinks when pasting remote files (#3406)

This commit is contained in:
三咲雅 misaki masa 2025-12-05 23:22:47 +08:00 committed by sxyazi
parent 205b7fe11f
commit c569263a50
No known key found for this signature in database
11 changed files with 120 additions and 93 deletions

View file

@ -21,7 +21,7 @@ fn path_relative_to_impl<'a>(from: PathCow<'_>, to: PathCow<'a>) -> Result<PathC
}
if from == to {
return Ok(PathDyn::with_str(to.kind(), ".").into());
return Ok(PathDyn::with_str(from.kind(), ".").into());
}
let (mut f_it, mut t_it) = (from.components(), to.components());
@ -41,7 +41,7 @@ fn path_relative_to_impl<'a>(from: PathCow<'_>, to: PathCow<'a>) -> Result<PathC
let dots = f_head.into_iter().chain(f_it).map(|_| ParentDir);
let rest = t_head.into_iter().chain(t_it);
let buf = PathBufDyn::from_components(to.kind(), dots.chain(rest))?;
let buf = PathBufDyn::from_components(from.kind(), dots.chain(rest))?;
Ok(buf.into())
}

View file

@ -1,7 +1,7 @@
use std::{io, path::Path, sync::Arc};
use tokio::sync::mpsc;
use yazi_shared::{path::{AsPath, PathBufDyn}, scheme::SchemeKind, url::{Url, UrlBuf, UrlCow}};
use yazi_shared::{path::{AsPath, PathBufDyn}, scheme::SchemeKind, strand::AsStrand, url::{Url, UrlBuf, UrlCow}};
use crate::{cha::Cha, path::absolute_url, provider::{Attrs, Provider}};
@ -120,14 +120,14 @@ impl<'a> Provider for Local<'a> {
}
#[inline]
async fn symlink<P, F>(&self, original: P, _is_dir: F) -> io::Result<()>
async fn symlink<S, F>(&self, original: S, _is_dir: F) -> io::Result<()>
where
P: AsPath,
S: AsStrand,
F: AsyncFnOnce() -> io::Result<bool>,
{
#[cfg(unix)]
{
let original = original.as_path().as_os()?;
let original = original.as_strand().as_os()?;
tokio::fs::symlink(original, self.path).await
}
#[cfg(windows)]
@ -139,11 +139,11 @@ impl<'a> Provider for Local<'a> {
}
#[inline]
async fn symlink_dir<P>(&self, original: P) -> io::Result<()>
async fn symlink_dir<S>(&self, original: S) -> io::Result<()>
where
P: AsPath,
S: AsStrand,
{
let original = original.as_path().as_os()?;
let original = original.as_strand().as_os()?;
#[cfg(unix)]
{
@ -156,11 +156,11 @@ impl<'a> Provider for Local<'a> {
}
#[inline]
async fn symlink_file<P>(&self, original: P) -> io::Result<()>
async fn symlink_file<S>(&self, original: S) -> io::Result<()>
where
P: AsPath,
S: AsStrand,
{
let original = original.as_path().as_os()?;
let original = original.as_strand().as_os()?;
#[cfg(unix)]
{

View file

@ -2,7 +2,7 @@ use std::io;
use tokio::{io::{AsyncRead, AsyncSeek, AsyncWrite, AsyncWriteExt}, sync::mpsc};
use yazi_macro::ok_or_not_found;
use yazi_shared::{path::{AsPath, PathBufDyn}, strand::StrandCow, url::{AsUrl, Url, UrlBuf}};
use yazi_shared::{path::{AsPath, PathBufDyn}, strand::{AsStrand, StrandCow}, url::{AsUrl, Url, UrlBuf}};
use crate::{cha::{Cha, ChaType}, provider::Attrs};
@ -155,21 +155,21 @@ pub trait Provider: Sized {
where
P: AsPath;
fn symlink<P, F>(&self, original: P, _is_dir: F) -> impl Future<Output = io::Result<()>>
fn symlink<S, F>(&self, original: S, _is_dir: F) -> impl Future<Output = io::Result<()>>
where
P: AsPath,
S: AsStrand,
F: AsyncFnOnce() -> io::Result<bool>;
fn symlink_dir<P>(&self, original: P) -> impl Future<Output = io::Result<()>>
fn symlink_dir<S>(&self, original: S) -> impl Future<Output = io::Result<()>>
where
P: AsPath,
S: AsStrand,
{
self.symlink(original, async || Ok(true))
}
fn symlink_file<P>(&self, original: P) -> impl Future<Output = io::Result<()>>
fn symlink_file<S>(&self, original: S) -> impl Future<Output = io::Result<()>>
where
P: AsPath,
S: AsStrand,
{
self.symlink(original, async || Ok(false))
}