diff --git a/Cargo.lock b/Cargo.lock index 9a39f219..56e1d381 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1025,7 +1025,7 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", ] [[package]] @@ -1470,7 +1470,7 @@ checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.59.0", ] @@ -2992,9 +2992,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" @@ -3318,9 +3318,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" dependencies = [ "memchr", ] diff --git a/yazi-core/src/mgr/commands/update_mimes.rs b/yazi-core/src/mgr/commands/update_mimes.rs index c10f6cb9..256d9249 100644 --- a/yazi-core/src/mgr/commands/update_mimes.rs +++ b/yazi-core/src/mgr/commands/update_mimes.rs @@ -7,7 +7,7 @@ use yazi_shared::{event::CmdCow, url::Url}; use crate::{mgr::{LINKED, Mgr}, tasks::Tasks}; pub struct Opt { - updates: HashMap, String>, + updates: HashMap, Cow<'static, str>>, } impl TryFrom for Opt { @@ -28,13 +28,13 @@ impl Mgr { let updates = opt .updates .into_iter() - .map(|(url, mime)| (Url::from(url.into_owned()), mime)) + .map(|(url, mime)| (Url::from(url.as_ref()), mime)) .filter(|(url, mime)| self.mimetype.by_url(url) != Some(mime)) .fold(HashMap::new(), |mut map, (u, m)| { for u in linked.from_file(&u) { - map.insert(u, m.clone()); + map.insert(u, m.to_string()); } - map.insert(u, m); + map.insert(u, m.into_owned()); map }); diff --git a/yazi-core/src/notify/commands/push.rs b/yazi-core/src/notify/commands/push.rs index 73e535ff..3fe2c232 100644 --- a/yazi-core/src/notify/commands/push.rs +++ b/yazi-core/src/notify/commands/push.rs @@ -14,7 +14,7 @@ impl Notify { if self.messages.iter().all(|m| m != &msg) { self.messages.push(msg); - emit!(Call(Cmd::args("app:update_notify", &[0]))); + emit!(Call(Cmd::args("app:update_notify", [0]))); } } } diff --git a/yazi-core/src/notify/commands/tick.rs b/yazi-core/src/notify/commands/tick.rs index c9ba8021..5646de3f 100644 --- a/yazi-core/src/notify/commands/tick.rs +++ b/yazi-core/src/notify/commands/tick.rs @@ -69,7 +69,7 @@ impl Notify { self.tick_handle = Some(tokio::spawn(async move { tokio::time::sleep(interval).await; - emit!(Call(Cmd::args("app:update_notify", &[interval.as_secs_f64()]))); + emit!(Call(Cmd::args("app:update_notify", [interval.as_secs_f64()]))); })); } } diff --git a/yazi-core/src/tab/commands/filter.rs b/yazi-core/src/tab/commands/filter.rs index 8682b14a..d5af509a 100644 --- a/yazi-core/src/tab/commands/filter.rs +++ b/yazi-core/src/tab/commands/filter.rs @@ -41,10 +41,10 @@ impl Tab { let (Ok(s) | Err(InputError::Typed(s))) = result else { continue }; emit!(Call( - Cmd::args("mgr:filter_do", &[s]) - .with_bool("smart", opt.case == FilterCase::Smart) - .with_bool("insensitive", opt.case == FilterCase::Insensitive) - .with_bool("done", done) + Cmd::args("mgr:filter_do", [s]) + .with("smart", opt.case == FilterCase::Smart) + .with("insensitive", opt.case == FilterCase::Insensitive) + .with("done", done) )); } }); diff --git a/yazi-core/src/tab/commands/find.rs b/yazi-core/src/tab/commands/find.rs index 5fc235bb..6537730f 100644 --- a/yazi-core/src/tab/commands/find.rs +++ b/yazi-core/src/tab/commands/find.rs @@ -33,10 +33,10 @@ impl Tab { while let Some(Ok(s)) | Some(Err(InputError::Typed(s))) = rx.next().await { emit!(Call( - Cmd::args("mgr:find_do", &[s]) - .with_bool("previous", opt.prev) - .with_bool("smart", opt.case == FilterCase::Smart) - .with_bool("insensitive", opt.case == FilterCase::Insensitive) + Cmd::args("mgr:find_do", [s]) + .with("previous", opt.prev) + .with("smart", opt.case == FilterCase::Smart) + .with("insensitive", opt.case == FilterCase::Insensitive) )); } }); diff --git a/yazi-core/src/tab/commands/search.rs b/yazi-core/src/tab/commands/search.rs index febbc4d2..fcb28852 100644 --- a/yazi-core/src/tab/commands/search.rs +++ b/yazi-core/src/tab/commands/search.rs @@ -20,7 +20,8 @@ impl Tab { handle.abort(); } - let mut input = InputProxy::show(InputCfg::search(opt.via.as_ref()).with_value(&*opt.subject)); + let mut input = + InputProxy::show(InputCfg::search(opt.via.into_str()).with_value(&*opt.subject)); tokio::spawn(async move { if let Some(Ok(subject)) = input.recv().await { opt.subject = Cow::Owned(subject); diff --git a/yazi-dds/src/sendable.rs b/yazi-dds/src/sendable.rs index c3518feb..3ff207a3 100644 --- a/yazi-dds/src/sendable.rs +++ b/yazi-dds/src/sendable.rs @@ -15,7 +15,7 @@ impl Sendable { Value::Number(n) => Data::Number(n), Value::String(b) => { if let Ok(s) = b.to_str() { - Data::String(s.to_owned()) + Data::String(s.to_owned().into()) } else { Data::Bytes(b.as_bytes().to_owned()) } @@ -99,7 +99,7 @@ impl Sendable { Data::Boolean(b) => Value::Boolean(*b), Data::Integer(i) => Value::Integer(*i), Data::Number(n) => Value::Number(*n), - Data::String(s) => Value::String(lua.create_string(s)?), + Data::String(s) => Value::String(lua.create_string(s.as_ref())?), Data::List(l) => { let mut vec = Vec::with_capacity(l.len()); for v in l { diff --git a/yazi-fm/src/app/app.rs b/yazi-fm/src/app/app.rs index e97fd239..c9304a31 100644 --- a/yazi-fm/src/app/app.rs +++ b/yazi-fm/src/app/app.rs @@ -25,24 +25,19 @@ impl App { app.render(); let mut events = Vec::with_capacity(50); + let (mut timeout, mut last_render) = (None, Instant::now()); macro_rules! drain_events { () => { for event in events.drain(..) { app.dispatch(event)?; - try_render!(); - } - }; - } + if !NEED_RENDER.load(Ordering::Relaxed) { + continue; + } - let (mut timeout, mut last_render) = (None, Instant::now()); - macro_rules! try_render { - () => { - if NEED_RENDER.load(Ordering::Relaxed) { - if let Some(sub) = Duration::from_millis(10).checked_sub(last_render.elapsed()) { - timeout = Some(sleep(sub)); - } else { + timeout = Duration::from_millis(10).checked_sub(last_render.elapsed()); + if timeout.is_none() { app.render(); - (timeout, last_render) = (None, Instant::now()); + last_render = Instant::now(); } } }; @@ -51,7 +46,7 @@ impl App { loop { if let Some(t) = timeout.take() { select! { - _ = t => { + _ = sleep(t) => { app.render(); last_render = Instant::now(); } diff --git a/yazi-fm/src/executor.rs b/yazi-fm/src/executor.rs index 98119342..704f9e48 100644 --- a/yazi-fm/src/executor.rs +++ b/yazi-fm/src/executor.rs @@ -141,7 +141,7 @@ impl<'a> Executor<'a> { on!(TABS, switch); on!(TABS, swap); - match cmd.name.as_str() { + match cmd.name.as_ref() { // Help "help" => self.app.cx.help.toggle(Layer::Mgr), // Plugin @@ -172,7 +172,7 @@ impl<'a> Executor<'a> { on!(open_with); on!(process_exec); - match cmd.name.as_str() { + match cmd.name.as_ref() { // Help "help" => self.app.cx.help.toggle(Layer::Tasks), // Plugin @@ -195,7 +195,7 @@ impl<'a> Executor<'a> { on!(swipe); on!(copy); - match cmd.name.as_str() { + match cmd.name.as_ref() { // Help "help" => self.app.cx.help.toggle(Layer::Spot), // Plugin @@ -217,7 +217,7 @@ impl<'a> Executor<'a> { on!(close); on!(arrow); - match cmd.name.as_str() { + match cmd.name.as_ref() { // Help "help" => self.app.cx.help.toggle(Layer::Pick), // Plugin @@ -241,7 +241,7 @@ impl<'a> Executor<'a> { match self.app.cx.input.mode() { InputMode::Normal => { - match cmd.name.as_str() { + match cmd.name.as_ref() { // Help "help" => return self.app.cx.help.toggle(Layer::Input), // Plugin @@ -249,7 +249,7 @@ impl<'a> Executor<'a> { _ => {} } } - InputMode::Insert => match cmd.name.as_str() { + InputMode::Insert => match cmd.name.as_ref() { "complete" if cmd.bool("trigger") => return self.app.cx.cmp.trigger(cmd), _ => {} }, @@ -286,7 +286,7 @@ impl<'a> Executor<'a> { on!(arrow); on!(filter); - match cmd.name.as_str() { + match cmd.name.as_ref() { "close" => self.app.cx.help.toggle(Layer::Help), // Plugin "plugin" => self.app.plugin(cmd), @@ -308,7 +308,7 @@ impl<'a> Executor<'a> { on!(close); on!(arrow); - match cmd.name.as_str() { + match cmd.name.as_ref() { // Help "help" => self.app.cx.help.toggle(Layer::Cmp), // Plugin diff --git a/yazi-plugin/src/config/plugin.rs b/yazi-plugin/src/config/plugin.rs index e0979673..d68901eb 100644 --- a/yazi-plugin/src/config/plugin.rs +++ b/yazi-plugin/src/config/plugin.rs @@ -58,7 +58,7 @@ impl Fetcher { impl UserData for Fetcher { fn add_fields>(fields: &mut F) { - cached_field!(fields, cmd, |lua, me| lua.create_string(&me.inner.run.name)); + cached_field!(fields, cmd, |lua, me| lua.create_string(me.inner.run.name.as_ref())); } } @@ -75,7 +75,7 @@ impl Spotter { impl UserData for Spotter { fn add_fields>(fields: &mut F) { - cached_field!(fields, cmd, |lua, me| lua.create_string(&me.inner.run.name)); + cached_field!(fields, cmd, |lua, me| lua.create_string(me.inner.run.name.as_ref())); } } @@ -92,7 +92,7 @@ impl Preloader { impl UserData for Preloader { fn add_fields>(fields: &mut F) { - cached_field!(fields, cmd, |lua, me| lua.create_string(&me.inner.run.name)); + cached_field!(fields, cmd, |lua, me| lua.create_string(me.inner.run.name.as_ref())); } } @@ -109,6 +109,6 @@ impl Previewer { impl UserData for Previewer { fn add_fields>(fields: &mut F) { - cached_field!(fields, cmd, |lua, me| lua.create_string(&me.inner.run.name)); + cached_field!(fields, cmd, |lua, me| lua.create_string(me.inner.run.name.as_ref())); } } diff --git a/yazi-plugin/src/isolate/peek.rs b/yazi-plugin/src/isolate/peek.rs index 3d9cd4c5..07e732db 100644 --- a/yazi-plugin/src/isolate/peek.rs +++ b/yazi-plugin/src/isolate/peek.rs @@ -19,7 +19,7 @@ pub fn peek( skip: usize, ) -> Option { let ct = CancellationToken::new(); - if let Some(c) = LOADER.read().get(&cmd.name) { + if let Some(c) = LOADER.read().get(cmd.name.as_ref()) { if c.sync_peek { peek_sync(cmd, file, mime, skip); } else { @@ -59,7 +59,7 @@ fn peek_sync(cmd: &'static Cmd, file: yazi_fs::File, mime: Cow<'static, str>, sk plugin.call_method("peek", job) }); - AppProxy::plugin(PluginOpt::new_callback(&cmd.name, cb)); + AppProxy::plugin(PluginOpt::new_callback(cmd.name.as_ref(), cb)); } fn peek_async( diff --git a/yazi-plugin/src/isolate/seek.rs b/yazi-plugin/src/isolate/seek.rs index 464cd34d..de7db600 100644 --- a/yazi-plugin/src/isolate/seek.rs +++ b/yazi-plugin/src/isolate/seek.rs @@ -16,5 +16,5 @@ pub fn seek_sync(cmd: &'static Cmd, file: yazi_fs::File, units: i16) { plugin.call_method("seek", job) }); - AppProxy::plugin(PluginOpt::new_callback(&cmd.name, cb)); + AppProxy::plugin(PluginOpt::new_callback(cmd.name.as_ref(), cb)); } diff --git a/yazi-plugin/src/utils/call.rs b/yazi-plugin/src/utils/call.rs index 54058f98..c80ae4ff 100644 --- a/yazi-plugin/src/utils/call.rs +++ b/yazi-plugin/src/utils/call.rs @@ -14,8 +14,8 @@ impl Utils { } pub(super) fn emit(lua: &Lua) -> mlua::Result { - lua.create_function(|_, (name, args): (mlua::String, Table)| { - let mut cmd = Cmd::new_or(&name.to_str()?, Layer::Mgr)?; + lua.create_function(|_, (name, args): (String, Table)| { + let mut cmd = Cmd::new_or(name, Layer::Mgr)?; cmd.args = Sendable::table_to_args(args)?; Ok(emit!(Call(cmd))) }) @@ -23,7 +23,11 @@ impl Utils { pub(super) fn mgr_emit(lua: &Lua) -> mlua::Result { lua.create_function(|_, (name, args): (String, Table)| { - emit!(Call(Cmd { name, args: Sendable::table_to_args(args)?, layer: Layer::Mgr })); + emit!(Call(Cmd { + name: name.into(), + args: Sendable::table_to_args(args)?, + layer: Layer::Mgr, + })); Ok(()) }) } diff --git a/yazi-plugin/src/utils/layer.rs b/yazi-plugin/src/utils/layer.rs index d886062a..71e4e8cf 100644 --- a/yazi-plugin/src/utils/layer.rs +++ b/yazi-plugin/src/utils/layer.rs @@ -21,7 +21,7 @@ impl Utils { let cand = cand?; cands.push(Chord { on: Self::parse_keys(cand.raw_get("on")?)?, - run: vec![Cmd::args("which:callback", &[i]).with_any("tx", tx.clone())], + run: vec![Cmd::args("which:callback", [i]).with_any("tx", tx.clone())], desc: cand.raw_get("desc").ok(), r#for: None, }); @@ -31,7 +31,7 @@ impl Utils { emit!(Call( Cmd::new("which:show") .with_any("candidates", cands) - .with_bool("silent", t.raw_get("silent").unwrap_or_default()) + .with("silent", t.raw_get::("silent").unwrap_or_default()) )); Ok(rx.recv().await.map(|idx| idx + 1)) diff --git a/yazi-proxy/src/cmp.rs b/yazi-proxy/src/cmp.rs index f33a9b53..53a8d8b1 100644 --- a/yazi-proxy/src/cmp.rs +++ b/yazi-proxy/src/cmp.rs @@ -11,6 +11,6 @@ impl CmpProxy { #[inline] pub fn trigger(word: &str, ticket: Id) { - emit!(Call(Cmd::args("cmp:trigger", &[word]).with("ticket", ticket))); + emit!(Call(Cmd::args("cmp:trigger", [word]).with("ticket", ticket))); } } diff --git a/yazi-proxy/src/mgr.rs b/yazi-proxy/src/mgr.rs index 7f7891da..83ef771b 100644 --- a/yazi-proxy/src/mgr.rs +++ b/yazi-proxy/src/mgr.rs @@ -13,7 +13,7 @@ impl MgrProxy { #[inline] pub fn peek(force: bool) { - emit!(Call(Cmd::new("mgr:peek").with_bool("force", force))); + emit!(Call(Cmd::new("mgr:peek").with("force", force))); } #[inline] @@ -34,7 +34,7 @@ impl MgrProxy { #[inline] pub fn remove_do(targets: Vec, permanently: bool) { emit!(Call( - Cmd::new("mgr:remove_do").with_bool("permanently", permanently).with_any("targets", targets) + Cmd::new("mgr:remove_do").with("permanently", permanently).with_any("targets", targets) )); } @@ -50,6 +50,6 @@ impl MgrProxy { #[inline] pub fn update_paged_by(page: usize, only_if: &Url) { - emit!(Call(Cmd::args("mgr:update_paged", &[page]).with_any("only-if", only_if.clone()))); + emit!(Call(Cmd::args("mgr:update_paged", [page]).with_any("only-if", only_if.clone()))); } } diff --git a/yazi-proxy/src/options/search.rs b/yazi-proxy/src/options/search.rs index abbaf1a0..05e11d53 100644 --- a/yazi-proxy/src/options/search.rs +++ b/yazi-proxy/src/options/search.rs @@ -33,7 +33,7 @@ impl TryFrom for SearchOpt { } // Via -#[derive(PartialEq, Eq)] +#[derive(Clone, Copy, PartialEq, Eq)] pub enum SearchOptVia { Rg, Rga, @@ -50,8 +50,8 @@ impl From<&str> for SearchOptVia { } } -impl AsRef for SearchOptVia { - fn as_ref(&self) -> &str { +impl SearchOptVia { + pub fn into_str(self) -> &'static str { match self { Self::Rg => "rg", Self::Rga => "rga", diff --git a/yazi-proxy/src/tab.rs b/yazi-proxy/src/tab.rs index e6b448a2..48672ece 100644 --- a/yazi-proxy/src/tab.rs +++ b/yazi-proxy/src/tab.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use yazi_macro::emit; use yazi_shared::{event::Cmd, url::Url}; @@ -8,25 +10,25 @@ pub struct TabProxy; impl TabProxy { #[inline] pub fn cd(target: &Url) { - emit!(Call(Cmd::args("mgr:cd", &[target]))); + emit!(Call(Cmd::args("mgr:cd", [target]))); } #[inline] pub fn reveal(target: &Url) { - emit!(Call(Cmd::args("mgr:reveal", &[target]).with("no-dummy", true))); + emit!(Call(Cmd::args("mgr:reveal", [target]).with("no-dummy", true))); } #[inline] - pub fn arrow(step: impl AsRef) { - emit!(Call(Cmd::args("mgr:arrow", &[step.as_ref()]))); + pub fn arrow(step: impl Into>) { + emit!(Call(Cmd::args("mgr:arrow", [step.into()]))); } #[inline] pub fn search_do(opt: SearchOpt) { emit!(Call( // TODO: use second positional argument instead of `args` parameter - Cmd::args("mgr:search_do", &[opt.subject]) - .with("via", opt.via.as_ref().to_owned()) + Cmd::args("mgr:search_do", [opt.subject]) + .with("via", Cow::Borrowed(opt.via.into_str())) .with("args", opt.args_raw.into_owned()) )); } diff --git a/yazi-shared/src/event/cmd.rs b/yazi-shared/src/event/cmd.rs index 9534ee84..9c64aa5c 100644 --- a/yazi-shared/src/event/cmd.rs +++ b/yazi-shared/src/event/cmd.rs @@ -1,4 +1,4 @@ -use std::{any::Any, borrow::Cow, collections::HashMap, fmt::{self, Display}, str::FromStr}; +use std::{any::Any, borrow::Cow, collections::HashMap, fmt::{self, Display}, mem, str::FromStr}; use anyhow::{Result, bail}; use serde::{Deserialize, de}; @@ -8,33 +8,48 @@ use crate::{Layer, url::Url}; #[derive(Debug, Default)] pub struct Cmd { - pub name: String, + pub name: Cow<'static, str>, pub args: HashMap, pub layer: Layer, } impl Cmd { - pub fn new(s: &str) -> Self { - Self::new_or(s, Default::default()) - .unwrap_or_else(|_| Self { name: "null".to_owned(), ..Default::default() }) + pub fn new(name: N) -> Self + where + N: Into>, + { + Self::new_or(name, Default::default()) + .unwrap_or_else(|_| Self { name: "null".into(), ..Default::default() }) } - pub fn new_or(s: &str, default: Layer) -> Result { - let (layer, name) = match s.split_once(':') { - Some((l, n)) => (l.parse()?, n), - None => (default, s), + pub fn new_or(name: N, default: Layer) -> Result + where + N: Into>, + { + let cow: Cow<'static, str> = name.into(); + let (layer, name) = match cow.find(':') { + None => (default, cow), + Some(i) => (cow[..i].parse()?, match cow { + Cow::Borrowed(s) => Cow::Borrowed(&s[i + 1..]), + Cow::Owned(mut s) => { + s.drain(..i + 1); + Cow::Owned(s) + } + }), }; - Ok(Self { name: name.to_owned(), args: Default::default(), layer }) + Ok(Self { name, args: Default::default(), layer }) } - pub fn args(name: &str, args: &[impl ToString]) -> Self { + pub fn args(name: N, args: I) -> Self + where + N: Into>, + D: Into, + I: IntoIterator, + { let mut me = Self::new(name); - me.args = args - .iter() - .enumerate() - .map(|(i, s)| (DataKey::Integer(i as i64), Data::String(s.to_string()))) - .collect(); + me.args = + args.into_iter().enumerate().map(|(i, a)| (DataKey::Integer(i as i64), a.into())).collect(); me } @@ -59,12 +74,6 @@ impl Cmd { self } - #[inline] - pub fn with_bool(mut self, name: impl Into, state: bool) -> Self { - self.args.insert(name.into(), Data::Boolean(state)); - self - } - #[inline] pub fn with_any(mut self, name: impl Into, data: impl Any + Send + Sync) -> Self { self.args.insert(name.into(), Data::Any(Box::new(data))); @@ -107,7 +116,7 @@ impl Cmd { } #[inline] - pub fn take_str(&mut self, name: impl Into) -> Option { + pub fn take_str(&mut self, name: impl Into) -> Option> { if let Some(Data::String(s)) = self.take(name) { Some(s) } else { None } } @@ -115,7 +124,7 @@ impl Cmd { pub fn take_first(&mut self) -> Option { self.take(0) } #[inline] - pub fn take_first_str(&mut self) -> Option { + pub fn take_first_str(&mut self) -> Option> { if let Some(Data::String(s)) = self.take_first() { Some(s) } else { None } } @@ -141,7 +150,7 @@ impl Cmd { .map(|(word, normal)| { let Some(arg) = word.strip_prefix("--").filter(|_| normal) else { i += 1; - return Ok((DataKey::Integer(i - obase as i64), Data::String(word))); + return Ok((DataKey::Integer(i - obase as i64), Data::String(word.into()))); }; let mut parts = arg.splitn(2, '='); @@ -150,7 +159,7 @@ impl Cmd { }; let val = if let Some(val) = parts.next() { - Data::String(val.to_owned()) + Data::String(val.to_owned().into()) } else { Data::Boolean(true) }; @@ -189,12 +198,12 @@ impl FromStr for Cmd { type Err = anyhow::Error; fn from_str(s: &str) -> Result { - let (words, last) = crate::shell::split_unix(s, true)?; + let (mut words, last) = crate::shell::split_unix(s, true)?; if words.is_empty() || words[0].is_empty() { bail!("command name cannot be empty"); } - let mut me = Self::new(&words[0]); + let mut me = Self::new(mem::take(&mut words[0])); me.args = Cmd::parse_args(words.into_iter().skip(1), last, true)?; Ok(me) } diff --git a/yazi-shared/src/event/cow.rs b/yazi-shared/src/event/cow.rs index 6f6e710c..b2aef0d2 100644 --- a/yazi-shared/src/event/cow.rs +++ b/yazi-shared/src/event/cow.rs @@ -40,7 +40,7 @@ impl CmdCow { #[inline] pub fn take_str(&mut self, name: impl Into) -> Option> { match self { - Self::Owned(c) => c.take_str(name).map(Cow::Owned), + Self::Owned(c) => c.take_str(name), Self::Borrowed(c) => c.str(name).map(Cow::Borrowed), } } @@ -56,7 +56,7 @@ impl CmdCow { #[inline] pub fn take_first_str(&mut self) -> Option> { match self { - Self::Owned(c) => c.take_first_str().map(Cow::Owned), + Self::Owned(c) => c.take_first_str(), Self::Borrowed(c) => c.first_str().map(Cow::Borrowed), } } diff --git a/yazi-shared/src/event/data.rs b/yazi-shared/src/event/data.rs index afe929d5..e2f824e5 100644 --- a/yazi-shared/src/event/data.rs +++ b/yazi-shared/src/event/data.rs @@ -12,7 +12,7 @@ pub enum Data { Boolean(bool), Integer(i64), Number(f64), - String(String), + String(Cow<'static, str>), List(Vec), Dict(HashMap), Id(Id), @@ -56,13 +56,13 @@ impl Data { #[inline] pub fn into_url(self) -> Option { match self { - Data::String(s) => Some(Url::from(s)), + Data::String(s) => Some(Url::from(s.as_ref())), Data::Url(u) => Some(u), _ => None, } } - pub fn into_dict_string(self) -> HashMap, String> { + pub fn into_dict_string(self) -> HashMap, Cow<'static, str>> { let Self::Dict(dict) = self else { return Default::default(); }; @@ -79,7 +79,7 @@ impl Data { #[inline] pub fn to_url(&self) -> Option { match self { - Self::String(s) => Some(Url::from(s)), + Self::String(s) => Some(Url::from(s.as_ref())), Self::Url(u) => Some(u.clone()), _ => None, } @@ -90,18 +90,34 @@ impl From for Data { fn from(value: bool) -> Self { Self::Boolean(value) } } +impl From for Data { + fn from(value: f64) -> Self { Self::Number(value) } +} + impl From for Data { fn from(value: usize) -> Self { Self::Id(value.into()) } } impl From for Data { - fn from(value: String) -> Self { Self::String(value) } + fn from(value: String) -> Self { Self::String(Cow::Owned(value)) } +} + +impl From> for Data { + fn from(value: Cow<'static, str>) -> Self { Self::String(value) } } impl From for Data { fn from(value: Id) -> Self { Self::Id(value) } } +impl From<&Url> for Data { + fn from(value: &Url) -> Self { Self::Url(value.clone()) } +} + +impl From<&str> for Data { + fn from(value: &str) -> Self { Self::String(Cow::Owned(value.to_owned())) } +} + // --- Key #[derive(Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] #[serde(untagged)]