diff --git a/Cargo.lock b/Cargo.lock index dc46cd88..2937f1be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -115,9 +115,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -1917,9 +1917,9 @@ dependencies = [ [[package]] name = "lua-src" -version = "548.1.1" +version = "548.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00bc4bd1f1d5c65b30717333cbec4fa7aa378978940a1bca62f404498d423233" +checksum = "bdc4e1aff422ad5f08cffb4719603dcdbc2be2307f4c1510d7aab74b7fa88ca8" dependencies = [ "cc", ] @@ -2003,9 +2003,9 @@ dependencies = [ [[package]] name = "mlua" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b3dd94c3c4dea0049b22296397040840a8f6b5b5229f438434ba82df402b42d" +checksum = "9be1c2bfc684b8a228fbaebf954af7a47a98ec27721986654a4cc2c40a20cc7e" dependencies = [ "anyhow", "bstr", @@ -2341,9 +2341,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "5.0.0" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2c1f9f56e534ac6a9b8a4600bdf0f530fb393b5f393e7b4d03489c3cf0c3f01" +checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d" dependencies = [ "num-traits", "rand 0.8.5", @@ -2732,9 +2732,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -2909,7 +2909,7 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.16", "libredox", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -3517,7 +3517,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "walkdir", ] @@ -3557,11 +3557,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.16", + "thiserror-impl 2.0.17", ] [[package]] @@ -3577,9 +3577,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -3884,9 +3884,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "unicode-ident" @@ -4764,7 +4764,7 @@ dependencies = [ "anyhow", "hashbrown 0.16.0", "mlua", - "ordered-float 5.0.0", + "ordered-float 5.1.0", "parking_lot", "paste", "serde", @@ -4879,7 +4879,7 @@ dependencies = [ "crossterm 0.29.0", "hashbrown 0.16.0", "mlua", - "ordered-float 5.0.0", + "ordered-float 5.1.0", "serde", "tokio", "yazi-binding", @@ -4957,7 +4957,7 @@ dependencies = [ "libc", "lru 0.16.1", "mlua", - "ordered-float 5.0.0", + "ordered-float 5.1.0", "parking_lot", "scopeguard", "serde", @@ -4998,7 +4998,7 @@ dependencies = [ "hashbrown 0.16.0", "libc", "memchr", - "ordered-float 5.0.0", + "ordered-float 5.1.0", "parking_lot", "percent-encoding", "serde", @@ -5031,9 +5031,7 @@ dependencies = [ "hashbrown 0.16.0", "parking_lot", "russh", - "serde", "tokio", - "toml 0.9.7", "tracing", "uzers", "yazi-config", @@ -5105,9 +5103,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zune-core" diff --git a/Cargo.toml b/Cargo.toml index 8372be97..212221f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,9 +35,9 @@ hashbrown = { version = "0.16.0", features = [ "serde" ] } indexmap = { version = "2.11.4", features = [ "serde" ] } libc = "0.2.176" lru = "0.16.1" -mlua = { version = "0.11.3", features = [ "anyhow", "async", "error-send", "lua54", "macros", "serde" ] } +mlua = { version = "0.11.4", features = [ "anyhow", "async", "error-send", "lua54", "macros", "serde" ] } objc = "0.2.7" -ordered-float = { version = "5.0.0", features = [ "serde" ] } +ordered-float = { version = "5.1.0", features = [ "serde" ] } parking_lot = "0.12.4" paste = "1.0.15" ratatui = { version = "0.29.0", features = [ "unstable-rendered-line-info", "unstable-widget-ref" ] } diff --git a/yazi-actor/src/mgr/open.rs b/yazi-actor/src/mgr/open.rs index 6a7d6668..6b409697 100644 --- a/yazi-actor/src/mgr/open.rs +++ b/yazi-actor/src/mgr/open.rs @@ -4,7 +4,7 @@ use yazi_fs::File; use yazi_macro::{act, succ}; use yazi_parser::mgr::{OpenDoOpt, OpenOpt}; use yazi_proxy::MgrProxy; -use yazi_shared::{data::Data, url::UrlCow}; +use yazi_shared::data::Data; use yazi_vfs::VfsFile; use crate::{Actor, Ctx, mgr::Quit}; @@ -17,27 +17,28 @@ impl Actor for Open { const NAME: &str = "open"; fn act(cx: &mut Ctx, mut opt: Self::Options) -> Result { - act!(mgr:escape_visual, cx)?; - - let Some(hovered) = cx.hovered().map(|h| h.url_owned()).map(UrlCow::from) else { succ!() }; - if !opt.interactive && ARGS.chooser_file.is_some() { succ!(if !opt.targets.is_empty() { Quit::with_selected(opt.targets) } else if opt.hovered { - Quit::with_selected([hovered]) + Quit::with_selected(cx.hovered().map(|h| &h.url)) } else { + act!(mgr:escape_visual, cx)?; Quit::with_selected(cx.tab().selected_or_hovered()) }); } if opt.targets.is_empty() { opt.targets = if opt.hovered { - vec![hovered.clone()] + cx.hovered().map(|h| vec![h.url.clone().into()]).unwrap_or_default() } else { + act!(mgr:escape_visual, cx)?; cx.tab().selected_or_hovered().cloned().map(Into::into).collect() }; } + if opt.targets.is_empty() { + succ!(); + } let todo: Vec<_> = opt .targets @@ -49,7 +50,7 @@ impl Actor for Open { let cwd = cx.cwd().clone(); if todo.is_empty() { - return act!(mgr:open_do, cx, OpenDoOpt { cwd, hovered, targets: opt.targets, interactive: opt.interactive }); + return act!(mgr:open_do, cx, OpenDoOpt { cwd, targets: opt.targets, interactive: opt.interactive }); } let scheduler = cx.tasks.scheduler.clone(); @@ -61,12 +62,7 @@ impl Actor for Open { } } if scheduler.fetch_mimetype(files).await { - MgrProxy::open_do(OpenDoOpt { - cwd, - hovered, - targets: opt.targets, - interactive: opt.interactive, - }); + MgrProxy::open_do(OpenDoOpt { cwd, targets: opt.targets, interactive: opt.interactive }); } }); succ!(); diff --git a/yazi-actor/src/mgr/open_do.rs b/yazi-actor/src/mgr/open_do.rs index a3575b15..9ce2f0a0 100644 --- a/yazi-actor/src/mgr/open_do.rs +++ b/yazi-actor/src/mgr/open_do.rs @@ -5,7 +5,7 @@ use yazi_config::{YAZI, popup::PickCfg}; use yazi_macro::succ; use yazi_parser::mgr::OpenDoOpt; use yazi_proxy::{PickProxy, TasksProxy}; -use yazi_shared::data::Data; +use yazi_shared::{data::Data, url::UrlCow}; use crate::{Actor, Ctx}; @@ -30,7 +30,7 @@ impl Actor for OpenDo { if targets.is_empty() { succ!(); } else if !opt.interactive { - succ!(cx.tasks.process_from_files(opt.cwd, opt.hovered, targets)); + succ!(cx.tasks.process_with_selected(opt.cwd, targets)); } let openers: Vec<_> = YAZI.opener.all(YAZI.open.common(&targets).into_iter()); @@ -39,10 +39,10 @@ impl Actor for OpenDo { } let pick = PickProxy::show(PickCfg::open(openers.iter().map(|o| o.desc()).collect())); - let urls = [opt.hovered].into_iter().chain(targets.into_iter().map(|(u, _)| u)).collect(); + let urls = [UrlCow::default()].into_iter().chain(targets.into_iter().map(|(u, _)| u)).collect(); tokio::spawn(async move { if let Ok(choice) = pick.await { - TasksProxy::open_with(Cow::Borrowed(openers[choice]), opt.cwd, urls); + TasksProxy::file_open(Cow::Borrowed(openers[choice]), opt.cwd, urls); } }); succ!(); diff --git a/yazi-actor/src/mgr/quit.rs b/yazi-actor/src/mgr/quit.rs index fc1a2a57..cded52a0 100644 --- a/yazi-actor/src/mgr/quit.rs +++ b/yazi-actor/src/mgr/quit.rs @@ -77,6 +77,8 @@ impl Quit { s }); - emit!(Quit(EventQuit { selected: Some(paths), ..Default::default() })); + if !paths.is_empty() { + emit!(Quit(EventQuit { selected: Some(paths), ..Default::default() })); + } } } diff --git a/yazi-actor/src/mgr/search.rs b/yazi-actor/src/mgr/search.rs index 2b576afa..224531d6 100644 --- a/yazi-actor/src/mgr/search.rs +++ b/yazi-actor/src/mgr/search.rs @@ -111,7 +111,7 @@ impl Actor for SearchStop { succ!(); } - let rep = tab.history.remove_or(&tab.cwd().to_regular()); + let rep = tab.history.remove_or(tab.cwd().to_regular()); drop(mem::replace(&mut tab.current, rep)); act!(mgr:hidden, cx)?; diff --git a/yazi-actor/src/mgr/shell.rs b/yazi-actor/src/mgr/shell.rs index 9b04fcfa..782c7a3f 100644 --- a/yazi-actor/src/mgr/shell.rs +++ b/yazi-actor/src/mgr/shell.rs @@ -37,7 +37,7 @@ impl Actor for Shell { return; } - TasksProxy::open_with( + TasksProxy::file_open( Cow::Owned(OpenerRule { run: opt.run.into_owned(), block: opt.block, diff --git a/yazi-actor/src/tasks/open_with.rs b/yazi-actor/src/tasks/file_open.rs similarity index 73% rename from yazi-actor/src/tasks/open_with.rs rename to yazi-actor/src/tasks/file_open.rs index b927d1a0..bdb635af 100644 --- a/yazi-actor/src/tasks/open_with.rs +++ b/yazi-actor/src/tasks/file_open.rs @@ -5,15 +5,15 @@ use yazi_shared::data::Data; use crate::{Actor, Ctx}; -pub struct OpenWith; +pub struct FileOpen; -impl Actor for OpenWith { +impl Actor for FileOpen { type Options = OpenWithOpt; - const NAME: &str = "open_with"; + const NAME: &str = "file_open"; fn act(cx: &mut Ctx, opt: Self::Options) -> Result { - succ!(cx.tasks.process_from_opener( + succ!(cx.tasks.process_with_opener( opt.cwd, opt.opener, opt.targets.into_iter().map(|u| u.into_os_str2()).collect(), diff --git a/yazi-actor/src/tasks/mod.rs b/yazi-actor/src/tasks/mod.rs index 83ce757d..af4b2fb9 100644 --- a/yazi-actor/src/tasks/mod.rs +++ b/yazi-actor/src/tasks/mod.rs @@ -1 +1 @@ -yazi_macro::mod_flat!(arrow cancel close inspect open_with process_exec show update_succeed); +yazi_macro::mod_flat!(arrow cancel close file_open inspect process_open show update_succeed); diff --git a/yazi-actor/src/tasks/process_exec.rs b/yazi-actor/src/tasks/process_open.rs similarity index 56% rename from yazi-actor/src/tasks/process_exec.rs rename to yazi-actor/src/tasks/process_open.rs index c5ece66f..502f789a 100644 --- a/yazi-actor/src/tasks/process_exec.rs +++ b/yazi-actor/src/tasks/process_open.rs @@ -1,16 +1,16 @@ use anyhow::Result; use yazi_macro::succ; -use yazi_parser::tasks::ProcessExecOpt; +use yazi_parser::tasks::ProcessOpenOpt; use yazi_shared::data::Data; use crate::{Actor, Ctx}; -pub struct ProcessExec; +pub struct ProcessOpen; -impl Actor for ProcessExec { - type Options = ProcessExecOpt; +impl Actor for ProcessOpen { + type Options = ProcessOpenOpt; - const NAME: &str = "process_exec"; + const NAME: &str = "process_open"; fn act(cx: &mut Ctx, opt: Self::Options) -> Result { succ!(cx.tasks.scheduler.process_open(opt)); diff --git a/yazi-binding/src/url.rs b/yazi-binding/src/url.rs index 6135d56d..30d200b6 100644 --- a/yazi-binding/src/url.rs +++ b/yazi-binding/src/url.rs @@ -1,7 +1,7 @@ use std::ops::Deref; use mlua::{AnyUserData, ExternalError, FromLua, Lua, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataRef, Value}; -use yazi_shared::{IntoOsStr, url::UrlCow}; +use yazi_shared::{IntoOsStr, url::{AsUrl, UrlCow}}; use crate::{Urn, cached_field, deprecate}; @@ -29,12 +29,16 @@ impl AsRef for Url { fn as_ref(&self) -> &yazi_shared::url::UrlBuf { &self.inner } } -impl From for yazi_shared::url::UrlBuf { - fn from(value: Url) -> Self { value.inner } +impl AsUrl for Url { + fn as_url(&self) -> yazi_shared::url::Url<'_> { self.inner.as_url() } } -impl<'a> From<&'a Url> for yazi_shared::url::Url<'a> { - fn from(value: &'a Url) -> Self { value.as_url() } +impl AsUrl for &Url { + fn as_url(&self) -> yazi_shared::url::Url<'_> { self.inner.as_url() } +} + +impl From for yazi_shared::url::UrlBuf { + fn from(value: Url) -> Self { value.inner } } impl<'a> From<&'a Url> for UrlCow<'a> { diff --git a/yazi-codegen/Cargo.toml b/yazi-codegen/Cargo.toml index 97741895..7b471bdd 100644 --- a/yazi-codegen/Cargo.toml +++ b/yazi-codegen/Cargo.toml @@ -14,4 +14,4 @@ proc-macro = true [dependencies] # External dependencies syn = { version = "2.0.106", features = [ "full" ] } -quote = "1.0.40" +quote = "1.0.41" diff --git a/yazi-config/src/open/open.rs b/yazi-config/src/open/open.rs index 4fcd7d70..05953e16 100644 --- a/yazi-config/src/open/open.rs +++ b/yazi-config/src/open/open.rs @@ -48,7 +48,7 @@ impl Open { M: AsRef, { let each: Vec> = targets - .into_iter() + .iter() .map(|(u, m)| self.all(u, m).collect::>()) .filter(|s| !s.is_empty()) .collect(); diff --git a/yazi-config/src/pattern.rs b/yazi-config/src/pattern.rs index 66e0cfb6..b3f337a1 100644 --- a/yazi-config/src/pattern.rs +++ b/yazi-config/src/pattern.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use anyhow::Result; use globset::GlobBuilder; use serde::Deserialize; -use yazi_shared::{scheme::{SchemeCow, SchemeRef}, url::Url}; +use yazi_shared::{scheme::{SchemeCow, SchemeRef}, url::AsUrl}; #[derive(Debug, Deserialize)] #[serde(try_from = "String")] @@ -17,8 +17,8 @@ pub struct Pattern { } impl Pattern { - pub fn match_url<'a>(&self, url: impl Into>, is_dir: bool) -> bool { - let url = url.into(); + pub fn match_url(&self, url: impl AsUrl, is_dir: bool) -> bool { + let url = url.as_url(); if is_dir != self.is_dir { return false; @@ -126,7 +126,7 @@ mod tests { use super::*; fn matches(glob: &str, url: &str) -> bool { - Pattern::from_str(glob).unwrap().match_url(&UrlCow::try_from(url).unwrap(), false) + Pattern::from_str(glob).unwrap().match_url(UrlCow::try_from(url).unwrap(), false) } #[cfg(unix)] diff --git a/yazi-core/src/tab/history.rs b/yazi-core/src/tab/history.rs index c5501209..befe7158 100644 --- a/yazi-core/src/tab/history.rs +++ b/yazi-core/src/tab/history.rs @@ -1,7 +1,7 @@ use std::ops::{Deref, DerefMut}; use hashbrown::HashMap; -use yazi_shared::url::{Url, UrlBuf}; +use yazi_shared::url::{AsUrl, UrlBuf}; use super::Folder; @@ -19,8 +19,8 @@ impl DerefMut for History { } impl History { - pub fn remove_or<'a>(&mut self, url: impl Into>) -> Folder { - let url = url.into(); + pub fn remove_or(&mut self, url: impl AsUrl) -> Folder { + let url = url.as_url(); self.0.remove(&url).unwrap_or_else(|| Folder::from(url)) } } diff --git a/yazi-core/src/tasks/process.rs b/yazi-core/src/tasks/process.rs index 72db4644..6db5ee3a 100644 --- a/yazi-core/src/tasks/process.rs +++ b/yazi-core/src/tasks/process.rs @@ -2,53 +2,47 @@ use std::{borrow::Cow, ffi::OsStr, mem}; use hashbrown::HashMap; use yazi_config::{YAZI, opener::OpenerRule}; -use yazi_parser::tasks::ProcessExecOpt; +use yazi_parser::tasks::ProcessOpenOpt; use yazi_shared::url::{UrlBuf, UrlCow}; use super::Tasks; impl Tasks { - pub fn process_from_files( - &self, - cwd: UrlBuf, - hovered: UrlCow<'static>, - targets: Vec<(UrlCow<'static>, &str)>, - ) { + pub fn process_with_selected(&self, cwd: UrlBuf, targets: Vec<(UrlCow<'static>, &str)>) { let mut openers = HashMap::new(); for (url, mime) in targets { if let Some(opener) = YAZI.opener.first(YAZI.open.all(&url, mime)) { - openers.entry(opener).or_insert_with(|| vec![hovered.clone()]).push(url); + openers + .entry(opener) + .or_insert_with(|| vec![OsStr::new("").into()]) + .push(url.into_os_str2()); } } for (opener, args) in openers { - self.process_from_opener( - cwd.clone(), - Cow::Borrowed(opener), - args.into_iter().map(|u| u.into_os_str2()).collect(), - ); + self.process_with_opener(cwd.clone(), Cow::Borrowed(opener), args); } } - pub fn process_from_opener( + pub fn process_with_opener( &self, cwd: UrlBuf, opener: Cow<'static, OpenerRule>, mut args: Vec>, ) { if opener.spread { - self.scheduler.process_open(ProcessExecOpt { cwd, opener, args, done: None }); + self.scheduler.process_open(ProcessOpenOpt { cwd, opener, args, done: None }); return; } if args.is_empty() { return; } if args.len() == 2 { - self.scheduler.process_open(ProcessExecOpt { cwd, opener, args, done: None }); + self.scheduler.process_open(ProcessOpenOpt { cwd, opener, args, done: None }); return; } let hovered = mem::take(&mut args[0]); for target in args.into_iter().skip(1) { - self.scheduler.process_open(ProcessExecOpt { + self.scheduler.process_open(ProcessOpenOpt { cwd: cwd.clone(), opener: opener.clone(), args: vec![hovered.clone(), target], diff --git a/yazi-dds/src/spark/spark.rs b/yazi-dds/src/spark/spark.rs index 8d881a8f..b7cb6d3e 100644 --- a/yazi-dds/src/spark/spark.rs +++ b/yazi-dds/src/spark/spark.rs @@ -108,7 +108,7 @@ pub enum Spark<'a> { SpotCopy(yazi_parser::spot::CopyOpt), // Tasks - TasksProcessExec(yazi_parser::tasks::ProcessExecOpt), + TasksProcessOpen(yazi_parser::tasks::ProcessOpenOpt), TasksUpdateSucceed(yazi_parser::tasks::UpdateSucceedOpt), // Which @@ -231,7 +231,7 @@ impl<'a> IntoLua for Spark<'a> { Self::SpotCopy(b) => b.into_lua(lua), // Tasks - Self::TasksProcessExec(b) => b.into_lua(lua), + Self::TasksProcessOpen(b) => b.into_lua(lua), Self::TasksUpdateSucceed(b) => b.into_lua(lua), // Which @@ -324,7 +324,7 @@ try_from_spark!(notify::TickOpt, notify:tick); try_from_spark!(pick::CloseOpt, pick:close); try_from_spark!(pick::ShowOpt, pick:show); try_from_spark!(spot::CopyOpt, spot:copy); -try_from_spark!(tasks::ProcessExecOpt, tasks:process_exec); +try_from_spark!(tasks::ProcessOpenOpt, tasks:process_open); try_from_spark!(tasks::UpdateSucceedOpt, tasks:update_succeed); try_from_spark!(which::CallbackOpt, which:callback); try_from_spark!(which::ShowOpt, which:show); diff --git a/yazi-fm/src/executor.rs b/yazi-fm/src/executor.rs index 84b3151e..07b4c1ad 100644 --- a/yazi-fm/src/executor.rs +++ b/yazi-fm/src/executor.rs @@ -164,8 +164,8 @@ impl<'a> Executor<'a> { on!(arrow); on!(inspect); on!(cancel); - on!(open_with); - on!(process_exec); + on!(file_open); + on!(process_open); match cmd.name.as_ref() { // Help diff --git a/yazi-fs/src/cha/cha.rs b/yazi-fs/src/cha/cha.rs index 43c81430..0fa50290 100644 --- a/yazi-fs/src/cha/cha.rs +++ b/yazi-fs/src/cha/cha.rs @@ -2,7 +2,7 @@ use std::{ffi::OsStr, fs::Metadata, ops::Deref, time::{Duration, SystemTime, UNI use anyhow::bail; use yazi_macro::{unix_either, win_either}; -use yazi_shared::url::Url; +use yazi_shared::url::AsUrl; use super::ChaKind; use crate::cha::{ChaMode, ChaType}; @@ -52,15 +52,15 @@ impl Cha { Self::from_bare(&meta).attach(ChaKind::hidden(name, &meta)) } - pub fn from_dummy<'a, U>(_url: U, r#type: Option) -> Self + pub fn from_dummy(_url: U, r#type: Option) -> Self where - U: Into>, + U: AsUrl, { let mut kind = ChaKind::DUMMY; let mode = r#type.map(ChaMode::from_bare).unwrap_or_default(); #[cfg(unix)] - if _url.into().urn().is_hidden() { + if _url.as_url().urn().is_hidden() { kind |= ChaKind::HIDDEN; } diff --git a/yazi-fs/src/provider/local/local.rs b/yazi-fs/src/provider/local/local.rs index 38e66e75..6ac46de2 100644 --- a/yazi-fs/src/provider/local/local.rs +++ b/yazi-fs/src/provider/local/local.rs @@ -1,6 +1,6 @@ use std::{io, path::{Path, PathBuf}}; -use yazi_shared::url::{Url, UrlCow}; +use yazi_shared::url::{AsUrl, UrlCow}; use crate::{cha::Cha, path::absolute_url, provider::Provider}; @@ -12,11 +12,11 @@ impl Provider for Local { type Gate = super::Gate; type ReadDir = super::ReadDir; - async fn absolute<'a, U>(&self, url: U) -> io::Result> + async fn absolute<'a, U>(&self, url: &'a U) -> io::Result> where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); if url.scheme.is_virtual() { Err(io::Error::new(io::ErrorKind::InvalidInput, "Not a local URL")) } else { diff --git a/yazi-fs/src/provider/traits.rs b/yazi-fs/src/provider/traits.rs index 1574b864..5895e263 100644 --- a/yazi-fs/src/provider/traits.rs +++ b/yazi-fs/src/provider/traits.rs @@ -2,7 +2,7 @@ use std::{borrow::Cow, ffi::OsStr, io, path::{Path, PathBuf}}; use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt}; use yazi_macro::ok_or_not_found; -use yazi_shared::{scheme::SchemeRef, url::{Url, UrlCow}}; +use yazi_shared::{scheme::SchemeRef, url::{AsUrl, UrlCow}}; use crate::cha::{Cha, ChaType}; @@ -11,9 +11,9 @@ pub trait Provider { type Gate: FileBuilder; type ReadDir: DirReader; - fn absolute<'a, U>(&self, url: U) -> impl Future>> + fn absolute<'a, U>(&self, url: &'a U) -> impl Future>> where - U: Into>; + U: AsUrl; fn canonicalize

(&self, path: P) -> impl Future> where diff --git a/yazi-parser/src/mgr/open_do.rs b/yazi-parser/src/mgr/open_do.rs index 38c7cc4a..af38b273 100644 --- a/yazi-parser/src/mgr/open_do.rs +++ b/yazi-parser/src/mgr/open_do.rs @@ -4,7 +4,6 @@ use yazi_shared::{event::CmdCow, url::{UrlBuf, UrlCow}}; #[derive(Debug, Default)] pub struct OpenDoOpt { pub cwd: UrlBuf, - pub hovered: UrlCow<'static>, pub targets: Vec>, pub interactive: bool, } diff --git a/yazi-parser/src/tasks/mod.rs b/yazi-parser/src/tasks/mod.rs index 9a6a8e2e..f6810693 100644 --- a/yazi-parser/src/tasks/mod.rs +++ b/yazi-parser/src/tasks/mod.rs @@ -1 +1 @@ -yazi_macro::mod_flat!(process_exec update_succeed); +yazi_macro::mod_flat!(process_open update_succeed); diff --git a/yazi-parser/src/tasks/process_exec.rs b/yazi-parser/src/tasks/process_open.rs similarity index 82% rename from yazi-parser/src/tasks/process_exec.rs rename to yazi-parser/src/tasks/process_open.rs index e6cf3325..2837e555 100644 --- a/yazi-parser/src/tasks/process_exec.rs +++ b/yazi-parser/src/tasks/process_open.rs @@ -8,25 +8,25 @@ use yazi_shared::{event::CmdCow, url::UrlBuf}; // --- Exec #[derive(Debug)] -pub struct ProcessExecOpt { +pub struct ProcessOpenOpt { pub cwd: UrlBuf, pub opener: Cow<'static, OpenerRule>, pub args: Vec>, pub done: Option>, } -impl TryFrom for ProcessExecOpt { +impl TryFrom for ProcessOpenOpt { type Error = anyhow::Error; fn try_from(mut c: CmdCow) -> Result { - c.take_any("option").ok_or_else(|| anyhow!("Missing 'option' in ProcessExecOpt")) + c.take_any("option").ok_or_else(|| anyhow!("Missing 'option' in ProcessOpenOpt")) } } -impl FromLua for ProcessExecOpt { +impl FromLua for ProcessOpenOpt { fn from_lua(_: Value, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } } -impl IntoLua for ProcessExecOpt { +impl IntoLua for ProcessOpenOpt { fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } } diff --git a/yazi-proxy/src/tasks.rs b/yazi-proxy/src/tasks.rs index c05411e9..9e7e37f5 100644 --- a/yazi-proxy/src/tasks.rs +++ b/yazi-proxy/src/tasks.rs @@ -3,14 +3,14 @@ use std::{borrow::Cow, ffi::OsStr}; use tokio::sync::oneshot; use yazi_config::opener::OpenerRule; use yazi_macro::{emit, relay}; -use yazi_parser::{mgr::OpenWithOpt, tasks::ProcessExecOpt}; +use yazi_parser::{mgr::OpenWithOpt, tasks::ProcessOpenOpt}; use yazi_shared::url::{UrlBuf, UrlCow}; pub struct TasksProxy; impl TasksProxy { - pub fn open_with(opener: Cow<'static, OpenerRule>, cwd: UrlBuf, targets: Vec>) { - emit!(Call(relay!(tasks:open_with).with_any("option", OpenWithOpt { opener, cwd, targets }))); + pub fn file_open(opener: Cow<'static, OpenerRule>, cwd: UrlBuf, targets: Vec>) { + emit!(Call(relay!(tasks:file_open).with_any("option", OpenWithOpt { opener, cwd, targets }))); } pub async fn process_exec( @@ -19,7 +19,7 @@ impl TasksProxy { args: Vec>, ) { let (tx, rx) = oneshot::channel(); - emit!(Call(relay!(tasks:process_exec).with_any("option", ProcessExecOpt { + emit!(Call(relay!(tasks:process_open).with_any("option", ProcessOpenOpt { cwd, opener, args, diff --git a/yazi-scheduler/src/file/file.rs b/yazi-scheduler/src/file/file.rs index a7722175..26676ae2 100644 --- a/yazi-scheduler/src/file/file.rs +++ b/yazi-scheduler/src/file/file.rs @@ -6,7 +6,7 @@ use tracing::warn; use yazi_config::YAZI; use yazi_fs::{cha::Cha, ok_or_not_found, path::{path_relative_to, skip_url}, provider::{DirReader, FileHolder}}; use yazi_macro::ok_or_not_found; -use yazi_shared::url::{Url, UrlBuf, UrlCow}; +use yazi_shared::url::{AsUrl, UrlBuf, UrlCow}; use yazi_vfs::{VfsCha, copy_with_progress, maybe_exists, provider::{self, DirEntry}}; use super::{FileInDelete, FileInHardlink, FileInLink, FileInPaste, FileInTrash}; @@ -289,8 +289,8 @@ impl File { } #[inline] - async fn cha<'a>(url: impl Into>, follow: bool) -> io::Result { - let url = url.into(); + async fn cha(url: impl AsUrl, follow: bool) -> io::Result { + let url = url.as_url(); let cha = provider::symlink_metadata(url).await?; Ok(if follow { Cha::from_follow(url, cha).await } else { cha }) } diff --git a/yazi-scheduler/src/scheduler.rs b/yazi-scheduler/src/scheduler.rs index 35b272dc..93e818bd 100644 --- a/yazi-scheduler/src/scheduler.rs +++ b/yazi-scheduler/src/scheduler.rs @@ -7,7 +7,7 @@ use tokio::{select, sync::{mpsc::{self, UnboundedReceiver}, oneshot}, task::Join use yazi_config::{YAZI, plugin::{Fetcher, Preloader}}; use yazi_dds::Pump; use yazi_fs::FsUrl; -use yazi_parser::{app::PluginOpt, tasks::ProcessExecOpt}; +use yazi_parser::{app::PluginOpt, tasks::ProcessOpenOpt}; use yazi_proxy::TasksProxy; use yazi_shared::{Id, Throttle, url::UrlBuf}; use yazi_vfs::{must_be_dir, provider, unique_name}; @@ -310,7 +310,7 @@ impl Scheduler { } } - pub fn process_open(&self, ProcessExecOpt { cwd, opener, args, done }: ProcessExecOpt) { + pub fn process_open(&self, ProcessOpenOpt { cwd, opener, args, done }: ProcessOpenOpt) { let name = { let args = args.iter().map(|a| a.to_string_lossy()).collect::>().join(" "); if args.is_empty() { diff --git a/yazi-sftp/src/error.rs b/yazi-sftp/src/error.rs index 9c1066a0..1fd74de9 100644 --- a/yazi-sftp/src/error.rs +++ b/yazi-sftp/src/error.rs @@ -33,7 +33,7 @@ impl From for std::io::Error { Error::IO(e) => e, Error::Serde(e) => Self::new(std::io::ErrorKind::InvalidData, e), Error::Status(status) => match status.code { - responses::StatusCode::Ok => Self::new(std::io::ErrorKind::Other, "unexpected OK"), + responses::StatusCode::Ok => Self::other("unexpected OK"), responses::StatusCode::Eof => Self::from(std::io::ErrorKind::UnexpectedEof), responses::StatusCode::NoSuchFile => Self::from(std::io::ErrorKind::NotFound), responses::StatusCode::PermissionDenied => Self::from(std::io::ErrorKind::PermissionDenied), diff --git a/yazi-sftp/src/operator.rs b/yazi-sftp/src/operator.rs index 05dc6934..58557aea 100644 --- a/yazi-sftp/src/operator.rs +++ b/yazi-sftp/src/operator.rs @@ -78,7 +78,7 @@ impl Operator { status.into() } - pub async fn fsetstat<'a>(&self, handle: &str, attrs: &'a Attrs) -> Result<(), Error> { + pub async fn fsetstat(&self, handle: &str, attrs: &Attrs) -> Result<(), Error> { let status: responses::Status = self.send(requests::FSetStat::new(handle, attrs)).await?; status.into() } diff --git a/yazi-shared/src/event/cmd.rs b/yazi-shared/src/event/cmd.rs index 2a35eb3c..259351ee 100644 --- a/yazi-shared/src/event/cmd.rs +++ b/yazi-shared/src/event/cmd.rs @@ -99,7 +99,7 @@ impl Cmd { T: TryFrom<&'a Data>, T::Error: Into, { - self.get(0).map_err(Into::into) + self.get(0) } pub fn second<'a, T>(&'a self) -> Result @@ -107,7 +107,7 @@ impl Cmd { T: TryFrom<&'a Data>, T::Error: Into, { - self.get(1).map_err(Into::into) + self.get(1) } pub fn seq<'a, T>(&'a self) -> Vec @@ -128,7 +128,7 @@ impl Cmd { } // --- Take - pub fn take<'a, T>(&mut self, name: impl Into) -> Result + pub fn take(&mut self, name: impl Into) -> Result where T: TryFrom, T::Error: Into, @@ -140,7 +140,7 @@ impl Cmd { } } - pub fn take_first<'a, T>(&mut self) -> Result + pub fn take_first(&mut self) -> Result where T: TryFrom, T::Error: Into, diff --git a/yazi-shared/src/url/buf.rs b/yazi-shared/src/url/buf.rs index bf78a70f..fa2d6c77 100644 --- a/yazi-shared/src/url/buf.rs +++ b/yazi-shared/src/url/buf.rs @@ -3,7 +3,7 @@ use std::{borrow::Cow, ffi::OsStr, fmt::{Debug, Formatter}, hash::BuildHasher, p use anyhow::Result; use serde::{Deserialize, Serialize}; -use crate::{loc::LocBuf, pool::Pool, scheme::{Scheme, SchemeRef}, url::{Components, Display, Encode, EncodeTilded, Uri, Url, UrlCow, Urn}}; +use crate::{loc::LocBuf, pool::Pool, scheme::{Scheme, SchemeRef}, url::{AsUrl, Components, Display, Encode, EncodeTilded, Uri, Url, UrlCow, Urn}}; #[derive(Clone, Default, Eq, Hash, PartialEq)] pub struct UrlBuf { @@ -108,18 +108,16 @@ impl UrlBuf { pub fn parent(&self) -> Option> { self.as_url().parent() } #[inline] - pub fn starts_with<'a>(&self, base: impl Into>) -> bool { - self.as_url().starts_with(base) - } + pub fn starts_with(&self, base: impl AsUrl) -> bool { self.as_url().starts_with(base) } #[inline] - pub fn ends_with<'a>(&self, child: impl Into>) -> bool { self.as_url().ends_with(child) } + pub fn ends_with(&self, child: impl AsUrl) -> bool { self.as_url().ends_with(child) } - pub fn strip_prefix<'a>(&self, base: impl Into>) -> Option<&Urn> { + pub fn strip_prefix(&self, base: impl AsUrl) -> Option<&Urn> { use Scheme as S; use SchemeRef as T; - let base = base.into(); + let base = base.as_url(); let prefix = self.loc.strip_prefix(base.loc).ok()?; Some(Urn::new(match (&self.scheme, base.scheme) { @@ -174,7 +172,7 @@ impl UrlBuf { impl UrlBuf { #[inline] - pub fn as_url(&self) -> Url<'_> { Url::from(self) } + pub fn as_url(&self) -> Url<'_> { Url { loc: self.loc.as_loc(), scheme: self.scheme.as_ref() } } #[inline] pub fn base(&self) -> Option> { self.as_url().base() } diff --git a/yazi-shared/src/url/cow.rs b/yazi-shared/src/url/cow.rs index 30e5a992..719e8054 100644 --- a/yazi-shared/src/url/cow.rs +++ b/yazi-shared/src/url/cow.rs @@ -33,10 +33,6 @@ impl From for UrlCow<'_> { fn from(value: UrlBuf) -> Self { Self::Owned { loc: value.loc, scheme: value.scheme.into() } } } -impl<'a> From<&'a UrlCow<'a>> for Url<'a> { - fn from(value: &'a UrlCow<'a>) -> Self { value.as_url() } -} - impl From> for UrlBuf { fn from(value: UrlCow<'_>) -> Self { value.into_owned() } } diff --git a/yazi-shared/src/url/traits.rs b/yazi-shared/src/url/traits.rs index d3f55b9c..58b2e5cb 100644 --- a/yazi-shared/src/url/traits.rs +++ b/yazi-shared/src/url/traits.rs @@ -1,4 +1,4 @@ -use crate::url::{Url, UrlCow}; +use crate::url::{Url, UrlBuf, UrlCow}; pub trait AsUrl { fn as_url(&self) -> Url<'_>; @@ -9,6 +9,21 @@ impl AsUrl for Url<'_> { fn as_url(&self) -> Url<'_> { *self } } +impl AsUrl for UrlBuf { + #[inline] + fn as_url(&self) -> Url<'_> { self.as_url() } +} + +impl AsUrl for &UrlBuf { + #[inline] + fn as_url(&self) -> Url<'_> { (**self).as_url() } +} + +impl AsUrl for &mut UrlBuf { + #[inline] + fn as_url(&self) -> Url<'_> { (**self).as_url() } +} + impl AsUrl for UrlCow<'_> { #[inline] fn as_url(&self) -> Url<'_> { self.as_url() } @@ -16,5 +31,13 @@ impl AsUrl for UrlCow<'_> { impl AsUrl for &UrlCow<'_> { #[inline] - fn as_url(&self) -> Url<'_> { (*self).as_url() } + fn as_url(&self) -> Url<'_> { (**self).as_url() } +} + +impl<'a, T: AsUrl> From<&'a T> for Url<'a> { + fn from(value: &'a T) -> Self { value.as_url() } +} + +impl<'a, T: AsUrl> From<&'a mut T> for Url<'a> { + fn from(value: &'a mut T) -> Self { value.as_url() } } diff --git a/yazi-shared/src/url/url.rs b/yazi-shared/src/url/url.rs index 608a4e4b..04edc737 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::{Components, Encode, Uri, UrlBuf, Urn}}; +use crate::{loc::{Loc, LocBuf}, scheme::SchemeRef, url::{AsUrl, Components, Encode, Uri, UrlBuf, Urn}}; #[derive(Clone, Copy, Eq, Hash, PartialEq)] pub struct Url<'a> { @@ -10,16 +10,6 @@ pub struct Url<'a> { pub scheme: SchemeRef<'a>, } -impl<'a> From<&'a UrlBuf> for Url<'a> { - fn from(value: &'a UrlBuf) -> Self { - Self { loc: value.loc.as_loc(), scheme: value.scheme.as_ref() } - } -} - -impl<'a> From<&'a mut UrlBuf> for Url<'a> { - fn from(value: &'a mut UrlBuf) -> Self { Self::from(&*value) } -} - // --- Eq impl PartialEq for Url<'_> { fn eq(&self, other: &UrlBuf) -> bool { *self == other.as_url() } @@ -142,14 +132,14 @@ impl<'a> Url<'a> { } #[inline] - pub fn starts_with<'b>(self, base: impl Into>) -> bool { - let base: Url = base.into(); + pub fn starts_with(self, base: impl AsUrl) -> bool { + let base = base.as_url(); self.scheme.covariant(base.scheme) && self.loc.starts_with(base.loc) } #[inline] - pub fn ends_with<'b>(self, child: impl Into>) -> bool { - let child: Url = child.into(); + pub fn ends_with(self, child: impl AsUrl) -> bool { + let child = child.as_url(); self.scheme.covariant(child.scheme) && self.loc.ends_with(child.loc) } @@ -160,8 +150,8 @@ impl<'a> Url<'a> { pub fn os_str(self) -> Cow<'a, OsStr> { self.components().os_str() } #[inline] - pub fn covariant(self, other: impl Into) -> bool { - let other = other.into(); + pub fn covariant(self, other: impl AsUrl) -> bool { + let other = other.as_url(); self.scheme.covariant(other.scheme) && self.loc == other.loc } diff --git a/yazi-vfs/Cargo.toml b/yazi-vfs/Cargo.toml index 814538a3..6161f26d 100644 --- a/yazi-vfs/Cargo.toml +++ b/yazi-vfs/Cargo.toml @@ -22,9 +22,7 @@ futures = { workspace = true } hashbrown = { workspace = true } parking_lot = { workspace = true } russh = { workspace = true } -serde = { workspace = true } tokio = { workspace = true } -toml = { workspace = true } tracing = { workspace = true } [target."cfg(unix)".dependencies] diff --git a/yazi-vfs/src/cha.rs b/yazi-vfs/src/cha.rs index 69312f2a..d93dcb8c 100644 --- a/yazi-vfs/src/cha.rs +++ b/yazi-vfs/src/cha.rs @@ -1,30 +1,30 @@ use std::io; use yazi_fs::cha::{Cha, ChaKind}; -use yazi_shared::url::Url; +use yazi_shared::url::AsUrl; use crate::provider; pub trait VfsCha: Sized { - fn from_url<'a>(url: impl Into>) -> impl Future>; + fn from_url(url: impl AsUrl) -> impl Future>; - fn from_follow<'a, U>(url: U, cha: Self) -> impl Future + fn from_follow(url: U, cha: Self) -> impl Future where - U: Into>; + U: AsUrl; } impl VfsCha for Cha { #[inline] - async fn from_url<'a>(url: impl Into>) -> io::Result { - let url = url.into(); + async fn from_url(url: impl AsUrl) -> io::Result { + let url = url.as_url(); Ok(Self::from_follow(url, provider::symlink_metadata(url).await?).await) } - async fn from_follow<'a, U>(url: U, mut cha: Self) -> Self + async fn from_follow(url: U, mut cha: Self) -> Self where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); let mut retain = cha.kind & (ChaKind::HIDDEN | ChaKind::SYSTEM); if cha.is_link() { diff --git a/yazi-vfs/src/fns.rs b/yazi-vfs/src/fns.rs index 66e484ab..d6ebeede 100644 --- a/yazi-vfs/src/fns.rs +++ b/yazi-vfs/src/fns.rs @@ -3,12 +3,12 @@ use std::{ffi::OsString, io}; use tokio::{select, sync::{mpsc, oneshot}}; use yazi_fs::cha::Cha; use yazi_macro::ok_or_not_found; -use yazi_shared::url::{Url, UrlBuf}; +use yazi_shared::url::{AsUrl, UrlBuf}; use crate::provider; #[inline] -pub async fn maybe_exists<'a>(url: impl Into>) -> bool { +pub async fn maybe_exists(url: impl AsUrl) -> bool { match provider::symlink_metadata(url).await { Ok(_) => true, Err(e) => e.kind() != io::ErrorKind::NotFound, @@ -16,7 +16,7 @@ pub async fn maybe_exists<'a>(url: impl Into>) -> bool { } #[inline] -pub async fn must_be_dir<'a>(url: impl Into>) -> bool { +pub async fn must_be_dir(url: impl AsUrl) -> bool { provider::metadata(url).await.is_ok_and(|m| m.is_dir()) } diff --git a/yazi-vfs/src/lib.rs b/yazi-vfs/src/lib.rs index 8abc3e7d..28b92170 100644 --- a/yazi-vfs/src/lib.rs +++ b/yazi-vfs/src/lib.rs @@ -1,3 +1,5 @@ +#![allow(clippy::if_same_then_else, clippy::unit_arg)] + yazi_macro::mod_pub!(provider); yazi_macro::mod_flat!(cha file files fns op); diff --git a/yazi-vfs/src/provider/calculator.rs b/yazi-vfs/src/provider/calculator.rs index d5397aad..db103d13 100644 --- a/yazi-vfs/src/provider/calculator.rs +++ b/yazi-vfs/src/provider/calculator.rs @@ -1,7 +1,7 @@ use std::{collections::VecDeque, io, time::{Duration, Instant}}; use yazi_fs::provider::{DirReader, FileHolder}; -use yazi_shared::{Either, url::{Url, UrlBuf}}; +use yazi_shared::{Either, url::{AsUrl, UrlBuf}}; use super::ReadDir; @@ -11,11 +11,11 @@ pub enum SizeCalculator { } impl SizeCalculator { - pub async fn new<'a, U>(url: U) -> io::Result + pub async fn new(url: U) -> io::Result where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); let cha = super::symlink_metadata(url).await?; Ok(if cha.is_dir() { Self::Dir(VecDeque::from([Either::Left(url.to_owned())])) @@ -24,9 +24,9 @@ impl SizeCalculator { }) } - pub async fn total<'a, U>(url: U) -> io::Result + pub async fn total(url: U) -> io::Result where - U: Into>, + U: AsUrl, { let mut it = Self::new(url).await?; let mut total = 0; diff --git a/yazi-vfs/src/provider/provider.rs b/yazi-vfs/src/provider/provider.rs index 036f8556..6628cb8f 100644 --- a/yazi-vfs/src/provider/provider.rs +++ b/yazi-vfs/src/provider/provider.rs @@ -2,23 +2,22 @@ use std::{io, path::{Path, PathBuf}}; use tokio::io::{BufReader, BufWriter}; use yazi_fs::{cha::Cha, provider::{Provider, local::Local}}; -use yazi_shared::{scheme::SchemeRef, url::{Url, UrlBuf, UrlCow}}; +use yazi_shared::{scheme::SchemeRef, url::{AsUrl, UrlBuf, UrlCow}}; use super::{Providers, ReadDir, RwFile}; -pub async fn absolute<'a, U>(url: U) -> io::Result> +pub async fn absolute<'a, U>(url: &'a U) -> io::Result> where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); - Providers::new(url).await?.absolute(url).await + Providers::new(url.as_url()).await?.absolute(url).await } -pub async fn calculate<'a, U>(url: U) -> io::Result +pub async fn calculate(url: U) -> io::Result where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); if let Some(path) = url.as_path() { yazi_fs::provider::local::SizeCalculator::total(path).await } else { @@ -26,11 +25,11 @@ where } } -pub async fn canonicalize<'a, U>(url: U) -> io::Result +pub async fn canonicalize(url: U) -> io::Result where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); let canon = Providers::new(url).await?.canonicalize(url.loc).await?; Ok(match url.scheme { @@ -42,11 +41,11 @@ where }) } -pub async fn casefold<'a, U>(url: U) -> io::Result +pub async fn casefold(url: U) -> io::Result where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); let fold = Providers::new(url).await?.casefold(url.loc).await?; Ok(match url.scheme { @@ -58,12 +57,12 @@ where }) } -pub async fn copy<'a, U, V>(from: U, to: V, cha: Cha) -> io::Result +pub async fn copy(from: U, to: V, cha: Cha) -> io::Result where - U: Into>, - V: Into>, + U: AsUrl, + V: AsUrl, { - let (from, to): (Url, Url) = (from.into(), to.into()); + let (from, to) = (from.as_url(), to.as_url()); match (from.as_path(), to.as_path()) { (Some(from), Some(to)) => Local.copy(from, to, cha).await, @@ -85,36 +84,36 @@ where } } -pub async fn create<'a, U>(url: U) -> io::Result +pub async fn create(url: U) -> io::Result where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); Providers::new(url).await?.create(url.loc).await } -pub async fn create_dir<'a, U>(url: U) -> io::Result<()> +pub async fn create_dir(url: U) -> io::Result<()> where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); Providers::new(url).await?.create_dir(url.loc).await } -pub async fn create_dir_all<'a, U>(url: U) -> io::Result<()> +pub async fn create_dir_all(url: U) -> io::Result<()> where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); Providers::new(url).await?.create_dir_all(url.loc).await } -pub async fn hard_link<'a, U, V>(original: U, link: V) -> io::Result<()> +pub async fn hard_link(original: U, link: V) -> io::Result<()> where - U: Into>, - V: Into>, + U: AsUrl, + V: AsUrl, { - let (original, link): (Url, Url) = (original.into(), link.into()); + let (original, link) = (original.as_url(), link.as_url()); if original.scheme.covariant(link.scheme) { Providers::new(original).await?.hard_link(original.loc, link.loc).await } else { @@ -122,88 +121,88 @@ where } } -pub async fn identical<'a, U, V>(a: U, b: V) -> io::Result +pub async fn identical(a: U, b: V) -> io::Result where - U: Into>, - V: Into>, + U: AsUrl, + V: AsUrl, { - if let (Some(a), Some(b)) = (a.into().as_path(), b.into().as_path()) { + if let (Some(a), Some(b)) = (a.as_url().as_path(), b.as_url().as_path()) { yazi_fs::provider::local::identical(a, b).await } else { Err(io::Error::new(io::ErrorKind::Unsupported, "Unsupported filesystem")) } } -pub async fn metadata<'a, U>(url: U) -> io::Result +pub async fn metadata(url: U) -> io::Result where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); Providers::new(url).await?.metadata(url.loc).await } -pub async fn must_identical<'a, U, V>(a: U, b: V) -> bool +pub async fn must_identical(a: U, b: V) -> bool where - U: Into>, - V: Into>, + U: AsUrl, + V: AsUrl, { identical(a, b).await.unwrap_or(false) } -pub async fn read_dir<'a, U>(url: U) -> io::Result +pub async fn read_dir(url: U) -> io::Result where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); Providers::new(url).await?.read_dir(url.loc).await } -pub async fn read_link<'a, U>(url: U) -> io::Result +pub async fn read_link(url: U) -> io::Result where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); Providers::new(url).await?.read_link(url.loc).await } -pub async fn remove_dir<'a, U>(url: U) -> io::Result<()> +pub async fn remove_dir(url: U) -> io::Result<()> where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); Providers::new(url).await?.remove_dir(url.loc).await } -pub async fn remove_dir_all<'a, U>(url: U) -> io::Result<()> +pub async fn remove_dir_all(url: U) -> io::Result<()> where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); Providers::new(url).await?.remove_dir_all(url.loc).await } -pub async fn remove_dir_clean<'a, U>(url: U) -> io::Result<()> +pub async fn remove_dir_clean(url: U) -> io::Result<()> where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); Ok(Providers::new(url).await?.remove_dir_clean(url.loc).await) } -pub async fn remove_file<'a, U>(url: U) -> io::Result<()> +pub async fn remove_file(url: U) -> io::Result<()> where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); Providers::new(url).await?.remove_file(url.loc).await } -pub async fn rename<'a, U, V>(from: U, to: V) -> io::Result<()> +pub async fn rename(from: U, to: V) -> io::Result<()> where - U: Into>, - V: Into>, + U: AsUrl, + V: AsUrl, { - let (from, to): (Url, Url) = (from.into(), to.into()); + let (from, to) = (from.as_url(), to.as_url()); if from.scheme.covariant(to.scheme) { Providers::new(from).await?.rename(from.loc, to.loc).await } else { @@ -211,52 +210,52 @@ where } } -pub async fn symlink<'a, U, F>(original: &Path, link: U, is_dir: F) -> io::Result<()> +pub async fn symlink(original: &Path, link: U, is_dir: F) -> io::Result<()> where - U: Into>, + U: AsUrl, F: AsyncFnOnce() -> io::Result, { - let link: Url = link.into(); + let link = link.as_url(); Providers::new(link).await?.symlink(original, link.loc, is_dir).await } -pub async fn symlink_dir<'a, U>(original: &Path, link: U) -> io::Result<()> +pub async fn symlink_dir(original: &Path, link: U) -> io::Result<()> where - U: Into>, + U: AsUrl, { - let link: Url = link.into(); + let link = link.as_url(); Providers::new(link).await?.symlink_dir(original, link.loc).await } -pub async fn symlink_file<'a, U>(original: &Path, link: U) -> io::Result<()> +pub async fn symlink_file(original: &Path, link: U) -> io::Result<()> where - U: Into>, + U: AsUrl, { - let link: Url = link.into(); + let link = link.as_url(); Providers::new(link).await?.symlink_file(original, link.loc).await } -pub async fn symlink_metadata<'a, U>(url: U) -> io::Result +pub async fn symlink_metadata(url: U) -> io::Result where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); Providers::new(url).await?.symlink_metadata(url.loc).await } -pub async fn trash<'a, U>(url: U) -> io::Result<()> +pub async fn trash(url: U) -> io::Result<()> where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); Providers::new(url).await?.trash(url.loc).await } -pub async fn write<'a, U, C>(url: U, contents: C) -> io::Result<()> +pub async fn write(url: U, contents: C) -> io::Result<()> where - U: Into>, + U: AsUrl, C: AsRef<[u8]>, { - let url: Url = url.into(); + let url = url.as_url(); Providers::new(url).await?.write(url.loc, contents).await } diff --git a/yazi-vfs/src/provider/providers.rs b/yazi-vfs/src/provider/providers.rs index bc8bcdd8..80806270 100644 --- a/yazi-vfs/src/provider/providers.rs +++ b/yazi-vfs/src/provider/providers.rs @@ -2,7 +2,7 @@ use std::{io, path::{Path, PathBuf}, sync::Arc}; use yazi_config::vfs::{ProviderSftp, Vfs}; use yazi_fs::{cha::Cha, provider::{Provider, local::Local}}; -use yazi_shared::{scheme::SchemeRef, url::{Url, UrlCow}}; +use yazi_shared::{scheme::SchemeRef, url::{AsUrl, Url, UrlCow}}; pub(super) struct Providers<'a>(Inner<'a>); @@ -32,9 +32,9 @@ impl Provider for Providers<'_> { type Gate = super::Gate; type ReadDir = super::ReadDir; - async fn absolute<'a, U>(&self, url: U) -> io::Result> + async fn absolute<'a, U>(&self, url: &'a U) -> io::Result> where - U: Into>, + U: AsUrl, { match self.0 { Inner::Regular | Inner::Search(_) => Local.absolute(url).await, diff --git a/yazi-vfs/src/provider/sftp/sftp.rs b/yazi-vfs/src/provider/sftp/sftp.rs index 1dfd105a..d91f5e00 100644 --- a/yazi-vfs/src/provider/sftp/sftp.rs +++ b/yazi-vfs/src/provider/sftp/sftp.rs @@ -5,7 +5,7 @@ use tokio::io::{BufReader, BufWriter}; use yazi_config::vfs::ProviderSftp; use yazi_fs::provider::{DirReader, FileBuilder, FileHolder, Provider, local::Local}; use yazi_sftp::fs::{Attrs, Flags}; -use yazi_shared::{scheme::SchemeRef, url::{Url, UrlBuf, UrlCow}}; +use yazi_shared::{scheme::SchemeRef, url::{AsUrl, UrlBuf, UrlCow}}; use super::Cha; @@ -24,11 +24,11 @@ impl Provider for Sftp { type Gate = super::Gate; type ReadDir = super::ReadDir; - async fn absolute<'a, U>(&self, url: U) -> io::Result> + async fn absolute<'a, U>(&self, url: &'a U) -> io::Result> where - U: Into>, + U: AsUrl, { - let url: Url = url.into(); + let url = url.as_url(); Ok(if url.is_absolute() { url.into() } else if let SchemeRef::Sftp(_) = url.scheme { diff --git a/yazi-watcher/src/backend/backend.rs b/yazi-watcher/src/backend/backend.rs index 8fa23fdf..d9465e93 100644 --- a/yazi-watcher/src/backend/backend.rs +++ b/yazi-watcher/src/backend/backend.rs @@ -2,7 +2,7 @@ use anyhow::Result; use hashbrown::HashSet; use tokio::sync::mpsc; use tracing::error; -use yazi_shared::url::{Url, UrlBuf}; +use yazi_shared::url::{AsUrl, Url, UrlBuf}; use crate::{LINKED, WATCHED, backend}; @@ -64,11 +64,11 @@ impl Backend { todo.into_iter().for_each(|u| _ = out_tx.send(u)); } - fn watch<'a>(&mut self, url: impl Into>) -> Result<()> { - if let Some(path) = url.into().as_path() { self.local.watch(path) } else { Ok(()) } + fn watch(&mut self, url: impl AsUrl) -> Result<()> { + if let Some(path) = url.as_url().as_path() { self.local.watch(path) } else { Ok(()) } } - fn unwatch<'a>(&mut self, url: impl Into>) -> Result<()> { - if let Some(path) = url.into().as_path() { self.local.unwatch(path) } else { Ok(()) } + fn unwatch(&mut self, url: impl AsUrl) -> Result<()> { + if let Some(path) = url.as_url().as_path() { self.local.unwatch(path) } else { Ok(()) } } } diff --git a/yazi-watcher/src/linked.rs b/yazi-watcher/src/linked.rs index 13f9890c..819b7106 100644 --- a/yazi-watcher/src/linked.rs +++ b/yazi-watcher/src/linked.rs @@ -20,10 +20,10 @@ impl DerefMut for Linked { } impl Linked { - pub fn from_dir<'a, 'b, T>(&'a self, url: T) -> Box + 'b> + pub fn from_dir<'a, 'b, U>(&'a self, url: U) -> Box + 'b> where 'a: 'b, - T: Into>, + U: Into>, { let url: Url = url.into(); let Some(path) = url.as_path() else { diff --git a/yazi-watcher/src/watched.rs b/yazi-watcher/src/watched.rs index 5fb6f206..69528cfb 100644 --- a/yazi-watcher/src/watched.rs +++ b/yazi-watcher/src/watched.rs @@ -1,16 +1,14 @@ use std::path::Path; use hashbrown::HashSet; -use yazi_shared::url::{Url, UrlBuf}; +use yazi_shared::url::{AsUrl, UrlBuf}; #[derive(Default)] pub struct Watched(HashSet); impl Watched { #[inline] - pub(crate) fn contains<'a>(&self, url: impl Into>) -> bool { - self.0.contains(&url.into()) - } + pub(crate) fn contains(&self, url: impl AsUrl) -> bool { self.0.contains(&url.as_url()) } #[inline] pub(crate) fn diff(&self, new: &HashSet) -> (Vec, Vec) { @@ -26,5 +24,5 @@ impl Watched { } #[inline] - pub(crate) fn remove<'a>(&mut self, url: impl Into>) { self.0.remove(&url.into()); } + pub(crate) fn remove(&mut self, url: impl AsUrl) { self.0.remove(&url.as_url()); } }