fix: interoperability between number, integer, and id (#2883)

This commit is contained in:
三咲雅 misaki masa 2025-06-16 13:18:07 +08:00 committed by GitHub
parent a076ff8c82
commit 56a4e87d7e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 27 additions and 46 deletions

View file

@ -1,7 +1,6 @@
use std::time::Instant;
use std::time::{Duration, Instant};
use yazi_macro::emit;
use yazi_shared::event::Cmd;
use yazi_proxy::AppProxy;
use crate::notify::{Message, Notify};
@ -14,7 +13,7 @@ impl Notify {
if self.messages.iter().all(|m| m != &msg) {
self.messages.push(msg);
emit!(Call(Cmd::args("app:update_notify", [0])));
AppProxy::update_notify(Duration::ZERO);
}
}
}

View file

@ -1,7 +1,7 @@
use std::time::Duration;
use ratatui::layout::Rect;
use yazi_macro::emit;
use yazi_proxy::AppProxy;
use yazi_shared::event::{Cmd, CmdCow, Data};
use crate::notify::Notify;
@ -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()])));
AppProxy::update_notify(interval);
}));
}
}

View file

@ -9,24 +9,24 @@ use crate::options::{NotifyLevel, NotifyOpt, PluginOpt};
pub struct AppProxy;
impl AppProxy {
#[inline]
pub async fn stop() {
let (tx, rx) = oneshot::channel::<()>();
emit!(Call(Cmd::new("app:stop").with_any("tx", tx)));
rx.await.ok();
}
#[inline]
pub fn resume() {
emit!(Call(Cmd::new("app:resume")));
}
#[inline]
pub fn notify(opt: NotifyOpt) {
emit!(Call(Cmd::new("app:notify").with_any("option", opt)));
}
#[inline]
pub fn update_notify(dur: Duration) {
emit!(Call(Cmd::args("app:update_notify", [dur.as_secs_f64()])));
}
pub fn notify_warn(title: &str, content: impl ToString) {
Self::notify(NotifyOpt {
title: title.to_owned(),
@ -36,7 +36,6 @@ impl AppProxy {
});
}
#[inline]
pub fn notify_error(title: &str, content: impl ToString) {
Self::notify(NotifyOpt {
title: title.to_owned(),
@ -46,12 +45,10 @@ impl AppProxy {
});
}
#[inline]
pub fn plugin(opt: PluginOpt) {
emit!(Call(Cmd::new("app:plugin").with_any("opt", opt)));
}
#[inline]
pub fn plugin_do(opt: PluginOpt) {
emit!(Call(Cmd::new("app:plugin_do").with_any("opt", opt)));
}

View file

@ -4,12 +4,10 @@ use yazi_shared::{Id, event::Cmd};
pub struct CmpProxy;
impl CmpProxy {
#[inline]
pub fn close() {
emit!(Call(Cmd::new("cmp:close")));
}
#[inline]
pub fn trigger(word: &str, ticket: Id) {
emit!(Call(Cmd::args("cmp:trigger", [word]).with("ticket", ticket)));
}

View file

@ -6,10 +6,8 @@ use yazi_shared::event::Cmd;
pub struct ConfirmProxy;
impl ConfirmProxy {
#[inline]
pub async fn show(cfg: ConfirmCfg) -> bool { Self::show_rx(cfg).await.unwrap_or(false) }
#[inline]
pub fn show_rx(cfg: ConfirmCfg) -> oneshot::Receiver<bool> {
let (tx, rx) = oneshot::channel();
emit!(Call(Cmd::new("confirm:show").with_any("tx", tx).with_any("cfg", cfg)));

View file

@ -8,14 +8,12 @@ use crate::options::CmpItem;
pub struct InputProxy;
impl InputProxy {
#[inline]
pub fn show(cfg: InputCfg) -> mpsc::UnboundedReceiver<Result<String, InputError>> {
let (tx, rx) = mpsc::unbounded_channel();
emit!(Call(Cmd::new("input:show").with_any("tx", tx).with_any("cfg", cfg)));
rx
}
#[inline]
pub fn complete(item: &CmpItem, ticket: Id) {
emit!(Call(Cmd::new("input:complete").with_any("item", item.clone()).with("ticket", ticket)));
}

View file

@ -6,49 +6,40 @@ use crate::options::OpenDoOpt;
pub struct MgrProxy;
impl MgrProxy {
#[inline]
pub fn spot(skip: Option<usize>) {
emit!(Call(Cmd::new("mgr:spot").with_opt("skip", skip)));
}
#[inline]
pub fn peek(force: bool) {
emit!(Call(Cmd::new("mgr:peek").with("force", force)));
}
#[inline]
pub fn watch() {
emit!(Call(Cmd::new("mgr:watch")));
}
#[inline]
pub fn refresh() {
emit!(Call(Cmd::new("mgr:refresh")));
}
#[inline]
pub fn open_do(opt: OpenDoOpt) {
emit!(Call(Cmd::new("mgr:open_do").with_any("option", opt)));
}
#[inline]
pub fn remove_do(targets: Vec<Url>, permanently: bool) {
emit!(Call(
Cmd::new("mgr:remove_do").with("permanently", permanently).with_any("targets", targets)
));
}
#[inline]
pub fn update_tasks(url: &Url) {
emit!(Call(Cmd::new("mgr:update_tasks").with_any("urls", vec![url.clone()])));
}
#[inline]
pub fn update_paged() {
emit!(Call(Cmd::new("mgr:update_paged")));
}
#[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())));
}

View file

@ -52,7 +52,6 @@ pub enum NotifyLevel {
}
impl NotifyLevel {
#[inline]
pub fn icon(self) -> &'static str {
match self {
Self::Info => &THEME.notify.icon_info,
@ -61,7 +60,6 @@ impl NotifyLevel {
}
}
#[inline]
pub fn style(self) -> &'static Style {
match self {
Self::Info => &THEME.notify.title_info,

View file

@ -6,7 +6,6 @@ use yazi_shared::event::Cmd;
pub struct PickProxy;
impl PickProxy {
#[inline]
pub async fn show(cfg: PickCfg) -> anyhow::Result<usize> {
let (tx, rx) = oneshot::channel();
emit!(Call(Cmd::new("pick:show").with_any("tx", tx).with_any("cfg", cfg)));

View file

@ -8,22 +8,18 @@ use crate::options::SearchOpt;
pub struct TabProxy;
impl TabProxy {
#[inline]
pub fn cd(target: &Url) {
emit!(Call(Cmd::args("mgr:cd", [target])));
}
#[inline]
pub fn reveal(target: &Url) {
emit!(Call(Cmd::args("mgr:reveal", [target]).with("no-dummy", true)));
}
#[inline]
pub fn arrow(step: impl Into<Cow<'static, str>>) {
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

View file

@ -10,7 +10,6 @@ use crate::options::{OpenWithOpt, ProcessExecOpt};
pub struct TasksProxy;
impl TasksProxy {
#[inline]
pub fn open_with(opener: Cow<'static, OpenerRule>, cwd: Url, targets: Vec<Url>) {
emit!(Call(Cmd::new("tasks:open_with").with_any("option", OpenWithOpt {
opener,
@ -19,7 +18,6 @@ impl TasksProxy {
})));
}
#[inline]
pub async fn process_exec(opener: Cow<'static, OpenerRule>, cwd: Url, args: Vec<OsString>) {
let (tx, rx) = oneshot::channel();
emit!(Call(Cmd::new("tasks:process_exec").with_any("option", ProcessExecOpt {

View file

@ -90,6 +90,14 @@ impl From<bool> for Data {
fn from(value: bool) -> Self { Self::Boolean(value) }
}
impl From<i32> for Data {
fn from(value: i32) -> Self { Self::Integer(value as i64) }
}
impl From<i64> for Data {
fn from(value: i64) -> Self { Self::Integer(value) }
}
impl From<f64> for Data {
fn from(value: f64) -> Self { Self::Number(value) }
}
@ -187,7 +195,7 @@ impl From<String> for DataKey {
}
// --- Macros
macro_rules! impl_integer_as {
macro_rules! impl_as_integer {
($t:ty, $name:ident) => {
impl Data {
#[inline]
@ -203,14 +211,16 @@ macro_rules! impl_integer_as {
};
}
macro_rules! impl_number_as {
macro_rules! impl_as_number {
($t:ty, $name:ident) => {
impl Data {
#[inline]
pub fn $name(&self) -> Option<$t> {
match self {
Data::Integer(i) if *i == (*i as $t as _) => Some(*i as $t),
Data::Number(n) => <$t>::try_from(*n).ok(),
Data::String(s) => s.parse().ok(),
Data::Id(i) if i.0 == (i.0 as $t as _) => Some(i.0 as $t),
_ => None,
}
}
@ -218,11 +228,10 @@ macro_rules! impl_number_as {
};
}
impl_integer_as!(usize, as_usize);
impl_integer_as!(isize, as_isize);
impl_integer_as!(i16, as_i16);
impl_integer_as!(i32, as_i32);
impl_as_integer!(usize, as_usize);
impl_as_integer!(isize, as_isize);
impl_as_integer!(i16, as_i16);
impl_as_integer!(i32, as_i32);
impl_as_integer!(crate::Id, as_id);
impl_number_as!(f64, as_f64);
impl_integer_as!(crate::Id, as_id);
impl_as_number!(f64, as_f64);