mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
..
This commit is contained in:
parent
8ed0def9c6
commit
fd5cf1aad7
15 changed files with 133 additions and 174 deletions
|
|
@ -2,7 +2,7 @@ use std::{fmt, mem};
|
|||
|
||||
use anyhow::{bail, Result};
|
||||
use serde::{de::{self, Visitor}, Deserializer};
|
||||
use yazi_shared::event::{Arg, Cmd};
|
||||
use yazi_shared::event::{Cmd, Data};
|
||||
|
||||
pub(super) fn run_deserialize<'de, D>(deserializer: D) -> Result<Vec<Cmd>, D::Error>
|
||||
where
|
||||
|
|
@ -19,16 +19,16 @@ where
|
|||
let mut cmd = Cmd { name: mem::take(&mut args[0]), ..Default::default() };
|
||||
for (i, arg) in args.into_iter().skip(1).enumerate() {
|
||||
if !arg.starts_with("--") {
|
||||
cmd.args.insert(i.to_string(), Arg::String(arg));
|
||||
cmd.args.insert(i.to_string(), Data::String(arg));
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut parts = arg.splitn(2, '=');
|
||||
let key = parts.next().unwrap().trim_start_matches('-').to_owned();
|
||||
if let Some(val) = parts.next() {
|
||||
cmd.args.insert(key, Arg::String(val.to_owned()));
|
||||
cmd.args.insert(key, Data::String(val.to_owned()));
|
||||
} else {
|
||||
cmd.args.insert(key, Arg::Boolean(true));
|
||||
cmd.args.insert(key, Data::Boolean(true));
|
||||
}
|
||||
}
|
||||
Ok(cmd)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use yazi_dds::ValueSendable;
|
||||
use yazi_shared::{event::Cmd, fs::Url, render};
|
||||
use yazi_shared::{event::{Cmd, Data}, fs::Url, render};
|
||||
|
||||
use crate::{manager::{Manager, LINKED}, tasks::Tasks};
|
||||
|
||||
pub struct Opt {
|
||||
data: ValueSendable,
|
||||
data: Data,
|
||||
}
|
||||
|
||||
impl TryFrom<Cmd> for Opt {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
use yazi_dds::ValueSendable;
|
||||
use yazi_shared::event::Data;
|
||||
|
||||
use super::Tasks;
|
||||
|
||||
impl Tasks {
|
||||
#[inline]
|
||||
pub fn plugin_micro(&self, name: String, args: Vec<ValueSendable>) {
|
||||
pub fn plugin_micro(&self, name: String, args: Vec<Data>) {
|
||||
self.scheduler.plugin_micro(name, args);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn plugin_macro(&self, name: String, args: Vec<ValueSendable>) {
|
||||
pub fn plugin_macro(&self, name: String, args: Vec<Data>) {
|
||||
self.scheduler.plugin_macro(name, args);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,25 @@
|
|||
use mlua::{IntoLua, Lua, Value};
|
||||
use serde::Serialize;
|
||||
use yazi_shared::event::Data;
|
||||
|
||||
use super::Body;
|
||||
use crate::ValueSendable;
|
||||
use crate::Sendable;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BodyCustom {
|
||||
pub kind: String,
|
||||
pub value: ValueSendable,
|
||||
pub kind: String,
|
||||
pub data: Data,
|
||||
}
|
||||
|
||||
impl BodyCustom {
|
||||
#[inline]
|
||||
pub fn from_str(kind: &str, value: &str) -> anyhow::Result<Body<'static>> {
|
||||
Ok(Self { kind: kind.to_owned(), value: serde_json::from_str(value)? }.into())
|
||||
pub fn from_str(kind: &str, data: &str) -> anyhow::Result<Body<'static>> {
|
||||
Ok(Self { kind: kind.to_owned(), data: serde_json::from_str(data)? }.into())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_lua(kind: &str, value: Value) -> mlua::Result<Body<'static>> {
|
||||
Ok(Self { kind: kind.to_owned(), value: value.try_into()? }.into())
|
||||
pub fn from_lua(kind: &str, data: Value) -> mlua::Result<Body<'static>> {
|
||||
Ok(Self { kind: kind.to_owned(), data: Sendable::value_to_data(data)? }.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -27,11 +28,11 @@ impl From<BodyCustom> for Body<'_> {
|
|||
}
|
||||
|
||||
impl IntoLua<'_> for BodyCustom {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> { self.value.into_lua(lua) }
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> { Sendable::data_to_value(lua, self.data) }
|
||||
}
|
||||
|
||||
impl Serialize for BodyCustom {
|
||||
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
serde::Serialize::serialize(&self.value, serializer)
|
||||
serde::Serialize::serialize(&self.data, serializer)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,62 +1,26 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use mlua::{ExternalError, IntoLua, Lua, Value, Variadic};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use yazi_shared::OrderedFloat;
|
||||
use mlua::{ExternalError, Lua, Table, Value, Variadic};
|
||||
use yazi_shared::{event::{Data, DataKey}, OrderedFloat};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ValueSendable {
|
||||
Nil,
|
||||
Boolean(bool),
|
||||
Integer(i64),
|
||||
Number(f64),
|
||||
String(String),
|
||||
Table(HashMap<ValueSendableKey, ValueSendable>),
|
||||
}
|
||||
pub struct Sendable;
|
||||
|
||||
impl ValueSendable {
|
||||
pub fn try_from_variadic(values: Variadic<Value>) -> mlua::Result<Vec<Self>> {
|
||||
let mut vec = Vec::with_capacity(values.len());
|
||||
for value in values {
|
||||
vec.push(Self::try_from(value)?);
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
|
||||
pub fn into_table_string(self) -> HashMap<String, String> {
|
||||
let Self::Table(table) = self else {
|
||||
return Default::default();
|
||||
};
|
||||
|
||||
let mut map = HashMap::with_capacity(table.len());
|
||||
for pair in table {
|
||||
if let (ValueSendableKey::String(k), Self::String(v)) = pair {
|
||||
map.insert(k, v);
|
||||
}
|
||||
}
|
||||
map
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<Value<'a>> for ValueSendable {
|
||||
type Error = mlua::Error;
|
||||
|
||||
fn try_from(value: Value) -> Result<Self, Self::Error> {
|
||||
impl Sendable {
|
||||
pub fn value_to_data(value: Value) -> mlua::Result<Data> {
|
||||
Ok(match value {
|
||||
Value::Nil => Self::Nil,
|
||||
Value::Boolean(b) => Self::Boolean(b),
|
||||
Value::Nil => Data::Nil,
|
||||
Value::Boolean(b) => Data::Boolean(b),
|
||||
Value::LightUserData(_) => Err("light userdata is not supported".into_lua_err())?,
|
||||
Value::Integer(n) => Self::Integer(n),
|
||||
Value::Number(n) => Self::Number(n),
|
||||
Value::String(s) => Self::String(s.to_str()?.to_owned()),
|
||||
Value::Integer(n) => Data::Integer(n),
|
||||
Value::Number(n) => Data::Number(n),
|
||||
Value::String(s) => Data::String(s.to_str()?.to_owned()),
|
||||
Value::Table(t) => {
|
||||
let mut map = HashMap::with_capacity(t.len().map(|l| l as usize)?);
|
||||
for result in t.pairs::<Value, Value>() {
|
||||
let (k, v) = result?;
|
||||
map.insert(Self::try_from(k)?.try_into()?, v.try_into()?);
|
||||
map.insert(Self::value_to_key(k)?, Self::value_to_data(v)?);
|
||||
}
|
||||
Self::Table(map)
|
||||
Data::Table(map)
|
||||
}
|
||||
Value::Function(_) => Err("function is not supported".into_lua_err())?,
|
||||
Value::Thread(_) => Err("thread is not supported".into_lua_err())?,
|
||||
|
|
@ -64,66 +28,72 @@ impl<'a> TryFrom<Value<'a>> for ValueSendable {
|
|||
Value::Error(_) => Err("error is not supported".into_lua_err())?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoLua<'_> for ValueSendable {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
|
||||
match self {
|
||||
Self::Nil => Ok(Value::Nil),
|
||||
Self::Boolean(v) => Ok(Value::Boolean(v)),
|
||||
Self::Integer(v) => Ok(Value::Integer(v)),
|
||||
Self::Number(v) => Ok(Value::Number(v)),
|
||||
Self::String(v) => Ok(Value::String(lua.create_string(v)?)),
|
||||
Self::Table(v) => {
|
||||
pub fn value_to_key(value: Value) -> mlua::Result<DataKey> {
|
||||
Ok(match value {
|
||||
Value::Nil => DataKey::Nil,
|
||||
Value::Boolean(v) => DataKey::Boolean(v),
|
||||
Value::LightUserData(_) => Err("light userdata is not supported".into_lua_err())?,
|
||||
Value::Integer(v) => DataKey::Integer(v),
|
||||
Value::Number(v) => DataKey::Number(OrderedFloat::new(v)),
|
||||
Value::String(v) => DataKey::String(v.to_str()?.to_owned()),
|
||||
Value::Table(_) => Err("table is not supported".into_lua_err())?,
|
||||
Value::Function(_) => Err("function is not supported".into_lua_err())?,
|
||||
Value::Thread(_) => Err("thread is not supported".into_lua_err())?,
|
||||
Value::UserData(_) => Err("userdata is not supported".into_lua_err())?,
|
||||
Value::Error(_) => Err("error is not supported".into_lua_err())?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn data_to_value(lua: &Lua, data: Data) -> mlua::Result<Value> {
|
||||
match data {
|
||||
Data::Nil => Ok(Value::Nil),
|
||||
Data::Boolean(v) => Ok(Value::Boolean(v)),
|
||||
Data::Integer(v) => Ok(Value::Integer(v)),
|
||||
Data::Number(v) => Ok(Value::Number(v)),
|
||||
Data::String(v) => Ok(Value::String(lua.create_string(v)?)),
|
||||
Data::Table(v) => {
|
||||
let seq_len = v.keys().filter(|&k| !k.is_numeric()).count();
|
||||
let table = lua.create_table_with_capacity(seq_len, v.len() - seq_len)?;
|
||||
for (k, v) in v {
|
||||
table.raw_set(k, v)?;
|
||||
table.raw_set(Self::key_to_value(lua, k)?, Self::data_to_value(lua, v)?)?;
|
||||
}
|
||||
Ok(Value::Table(table))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ValueSendableKey {
|
||||
Nil,
|
||||
Boolean(bool),
|
||||
Integer(i64),
|
||||
Number(OrderedFloat),
|
||||
String(String),
|
||||
}
|
||||
|
||||
impl ValueSendableKey {
|
||||
#[inline]
|
||||
fn is_numeric(&self) -> bool { matches!(self, Self::Integer(_) | Self::Number(_)) }
|
||||
}
|
||||
|
||||
impl TryInto<ValueSendableKey> for ValueSendable {
|
||||
type Error = mlua::Error;
|
||||
|
||||
fn try_into(self) -> Result<ValueSendableKey, Self::Error> {
|
||||
Ok(match self {
|
||||
Self::Nil => ValueSendableKey::Nil,
|
||||
Self::Boolean(v) => ValueSendableKey::Boolean(v),
|
||||
Self::Integer(v) => ValueSendableKey::Integer(v),
|
||||
Self::Number(v) => ValueSendableKey::Number(OrderedFloat::new(v)),
|
||||
Self::String(v) => ValueSendableKey::String(v),
|
||||
Self::Table(_) => Err("table is not supported".into_lua_err())?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoLua<'_> for ValueSendableKey {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
|
||||
match self {
|
||||
Self::Nil => Ok(Value::Nil),
|
||||
Self::Boolean(k) => Ok(Value::Boolean(k)),
|
||||
Self::Integer(k) => Ok(Value::Integer(k)),
|
||||
Self::Number(k) => Ok(Value::Number(k.get())),
|
||||
Self::String(k) => Ok(Value::String(lua.create_string(k)?)),
|
||||
pub fn key_to_value(lua: &Lua, key: DataKey) -> mlua::Result<Value> {
|
||||
match key {
|
||||
DataKey::Nil => Ok(Value::Nil),
|
||||
DataKey::Boolean(k) => Ok(Value::Boolean(k)),
|
||||
DataKey::Integer(k) => Ok(Value::Integer(k)),
|
||||
DataKey::Number(k) => Ok(Value::Number(k.get())),
|
||||
DataKey::String(k) => Ok(Value::String(lua.create_string(k)?)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vec_to_table(lua: &Lua, data: Vec<Data>) -> mlua::Result<Table> {
|
||||
let mut vec = Vec::with_capacity(data.len());
|
||||
for v in data.into_iter() {
|
||||
vec.push(Self::data_to_value(lua, v)?);
|
||||
}
|
||||
lua.create_sequence_from(vec)
|
||||
}
|
||||
|
||||
pub fn vec_to_variadic(lua: &Lua, data: Vec<Data>) -> mlua::Result<Variadic<Value>> {
|
||||
let mut vec = Vec::with_capacity(data.len());
|
||||
for v in data {
|
||||
vec.push(Self::data_to_value(lua, v)?);
|
||||
}
|
||||
Ok(Variadic::from_iter(vec))
|
||||
}
|
||||
|
||||
pub fn variadic_to_vec(values: Variadic<Value>) -> mlua::Result<Vec<Data>> {
|
||||
let mut vec = Vec::with_capacity(values.len());
|
||||
for value in values {
|
||||
vec.push(Self::value_to_data(value)?);
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use std::fmt::Display;
|
|||
use mlua::TableExt;
|
||||
use scopeguard::defer;
|
||||
use tracing::warn;
|
||||
use yazi_dds::Sendable;
|
||||
use yazi_plugin::{loader::LOADER, OptData, RtRef, LUA};
|
||||
use yazi_shared::{emit, event::Cmd, Layer};
|
||||
|
||||
|
|
@ -56,7 +57,7 @@ impl App {
|
|||
if let Some(cb) = opt.data.cb {
|
||||
cb(&LUA, plugin)
|
||||
} else {
|
||||
plugin.call_method("entry", opt.data.args)
|
||||
plugin.call_method("entry", Sendable::vec_to_table(&LUA, opt.data.args)?)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
use mlua::{ExternalError, ExternalResult, Table, TableExt};
|
||||
use tokio::runtime::Handle;
|
||||
use yazi_dds::ValueSendable;
|
||||
use yazi_dds::Sendable;
|
||||
use yazi_shared::event::Data;
|
||||
|
||||
use super::slim_lua;
|
||||
use crate::loader::LOADER;
|
||||
|
||||
pub async fn entry(name: String, args: Vec<ValueSendable>) -> mlua::Result<()> {
|
||||
pub async fn entry(name: String, args: Vec<Data>) -> mlua::Result<()> {
|
||||
LOADER.ensure(&name).await.into_lua_err()?;
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
|
|
@ -16,7 +17,8 @@ pub async fn entry(name: String, args: Vec<ValueSendable>) -> mlua::Result<()> {
|
|||
return Err("unloaded plugin".into_lua_err());
|
||||
};
|
||||
|
||||
Handle::current().block_on(plugin.call_async_method("entry", args))
|
||||
Handle::current()
|
||||
.block_on(plugin.call_async_method("entry", Sendable::vec_to_table(&lua, args)))
|
||||
})
|
||||
.await
|
||||
.into_lua_err()?
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use anyhow::bail;
|
||||
use mlua::{Lua, Table};
|
||||
use yazi_dds::ValueSendable;
|
||||
use yazi_shared::event::Cmd;
|
||||
use yazi_shared::event::{Cmd, Data};
|
||||
|
||||
pub struct Opt {
|
||||
pub name: String,
|
||||
|
|
@ -11,7 +10,7 @@ pub struct Opt {
|
|||
|
||||
#[derive(Default)]
|
||||
pub struct OptData {
|
||||
pub args: Vec<ValueSendable>,
|
||||
pub args: Vec<Data>,
|
||||
pub cb: Option<Box<dyn FnOnce(&Lua, Table) -> mlua::Result<()> + Send>>,
|
||||
}
|
||||
|
||||
|
|
@ -26,7 +25,7 @@ impl TryFrom<Cmd> for Opt {
|
|||
let mut data: OptData = c.take_data().unwrap_or_default();
|
||||
|
||||
if let Some(args) = c.get_str("args") {
|
||||
data.args = shell_words::split(args)?.into_iter().map(ValueSendable::String).collect();
|
||||
data.args = shell_words::split(args)?.into_iter().map(Data::String).collect();
|
||||
}
|
||||
|
||||
Ok(Self { name, sync: c.get_bool("sync"), data })
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use mlua::{ExternalError, Lua, Table, Value};
|
||||
use yazi_dds::ValueSendable;
|
||||
use yazi_shared::{emit, event::Cmd, render, Layer};
|
||||
|
||||
use super::Utils;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use mlua::{ExternalError, ExternalResult, Function, IntoLua, Lua, Table, Value, Variadic};
|
||||
use tokio::sync::oneshot;
|
||||
use yazi_dds::ValueSendable;
|
||||
use yazi_shared::{emit, event::Cmd, Layer};
|
||||
use yazi_dds::Sendable;
|
||||
use yazi_shared::{emit, event::{Cmd, Data}, Layer};
|
||||
|
||||
use super::Utils;
|
||||
use crate::{loader::LOADER, runtime::RtRef, OptData};
|
||||
|
|
@ -37,7 +37,7 @@ impl Utils {
|
|||
return Err("`ya.sync()` must be called in a plugin").into_lua_err();
|
||||
};
|
||||
|
||||
Self::retrieve(cur, block, args).await
|
||||
Sendable::vec_to_variadic(lua, Self::retrieve(cur, block, args).await?)
|
||||
})
|
||||
})?,
|
||||
)?;
|
||||
|
|
@ -49,9 +49,9 @@ impl Utils {
|
|||
name: String,
|
||||
calls: usize,
|
||||
args: Variadic<Value<'_>>,
|
||||
) -> mlua::Result<mlua::Variadic<ValueSendable>> {
|
||||
let args = ValueSendable::try_from_variadic(args)?;
|
||||
let (tx, rx) = oneshot::channel::<Vec<ValueSendable>>();
|
||||
) -> mlua::Result<Vec<Data>> {
|
||||
let args = Sendable::variadic_to_vec(args)?;
|
||||
let (tx, rx) = oneshot::channel::<Vec<Data>>();
|
||||
|
||||
let data = OptData {
|
||||
cb: Some({
|
||||
|
|
@ -64,11 +64,10 @@ impl Utils {
|
|||
let mut self_args = Vec::with_capacity(args.len() + 1);
|
||||
self_args.push(Value::Table(plugin));
|
||||
for arg in args {
|
||||
self_args.push(arg.into_lua(lua)?);
|
||||
self_args.push(Sendable::data_to_value(lua, arg)?);
|
||||
}
|
||||
|
||||
let values =
|
||||
ValueSendable::try_from_variadic(block.call(Variadic::from_iter(self_args))?)?;
|
||||
let values = Sendable::variadic_to_vec(block.call(Variadic::from_iter(self_args))?)?;
|
||||
tx.send(values).map_err(|_| "send failed".into_lua_err())
|
||||
})
|
||||
}),
|
||||
|
|
@ -80,8 +79,8 @@ impl Utils {
|
|||
Layer::App
|
||||
));
|
||||
|
||||
Ok(Variadic::from_iter(rx.await.map_err(|_| {
|
||||
rx.await.map_err(|_| {
|
||||
format!("Failed to execute sync block-{calls} in `{name}` plugin").into_lua_err()
|
||||
})?))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use yazi_dds::ValueSendable;
|
||||
use yazi_shared::event::Data;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PluginOp {
|
||||
|
|
@ -17,5 +17,5 @@ impl PluginOp {
|
|||
pub struct PluginOpEntry {
|
||||
pub id: usize,
|
||||
pub name: String,
|
||||
pub args: Vec<ValueSendable>,
|
||||
pub args: Vec<Data>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use futures::{future::BoxFuture, FutureExt};
|
|||
use parking_lot::Mutex;
|
||||
use tokio::{fs, select, sync::{mpsc::{self, UnboundedReceiver}, oneshot}, task::JoinHandle};
|
||||
use yazi_config::{open::Opener, plugin::PluginRule, TASKS};
|
||||
use yazi_dds::{Pump, ValueSendable};
|
||||
use yazi_shared::{fs::{unique_path, Url}, Throttle};
|
||||
use yazi_dds::Pump;
|
||||
use yazi_shared::{event::Data, fs::{unique_path, Url}, Throttle};
|
||||
|
||||
use super::{Ongoing, TaskProg, TaskStage};
|
||||
use crate::{file::{File, FileOpDelete, FileOpLink, FileOpPaste, FileOpTrash}, plugin::{Plugin, PluginOpEntry}, preload::{Preload, PreloadOpRule, PreloadOpSize}, process::{Process, ProcessOpBg, ProcessOpBlock, ProcessOpOrphan}, TaskKind, TaskOp, HIGH, LOW, NORMAL};
|
||||
|
|
@ -182,7 +182,7 @@ impl Scheduler {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn plugin_micro(&self, name: String, args: Vec<ValueSendable>) {
|
||||
pub fn plugin_micro(&self, name: String, args: Vec<Data>) {
|
||||
let id = self.ongoing.lock().add(TaskKind::User, format!("Run micro plugin `{name}`"));
|
||||
|
||||
let plugin = self.plugin.clone();
|
||||
|
|
@ -195,7 +195,7 @@ impl Scheduler {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn plugin_macro(&self, name: String, args: Vec<ValueSendable>) {
|
||||
pub fn plugin_macro(&self, name: String, args: Vec<Data>) {
|
||||
let id = self.ongoing.lock().add(TaskKind::User, format!("Run macro plugin `{name}`"));
|
||||
|
||||
self.plugin.macro_(PluginOpEntry { id, name, args }).ok();
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
use std::{any::Any, collections::HashMap, fmt::{self, Display}};
|
||||
|
||||
use super::Arg;
|
||||
use super::Data;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Cmd {
|
||||
pub name: String,
|
||||
pub args: HashMap<String, Arg>,
|
||||
pub args: HashMap<String, Data>,
|
||||
pub data: Option<Box<dyn Any + Send>>,
|
||||
}
|
||||
|
||||
|
|
@ -17,20 +17,20 @@ impl Cmd {
|
|||
pub fn args(name: &str, args: Vec<String>) -> Self {
|
||||
Self {
|
||||
name: name.to_owned(),
|
||||
args: args.into_iter().enumerate().map(|(i, s)| (i.to_string(), Arg::String(s))).collect(),
|
||||
args: args.into_iter().enumerate().map(|(i, s)| (i.to_string(), Data::String(s))).collect(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with(mut self, name: impl ToString, value: impl ToString) -> Self {
|
||||
self.args.insert(name.to_string(), Arg::String(value.to_string()));
|
||||
self.args.insert(name.to_string(), Data::String(value.to_string()));
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_bool(mut self, name: impl ToString, state: bool) -> Self {
|
||||
self.args.insert(name.to_string(), Arg::Boolean(state));
|
||||
self.args.insert(name.to_string(), Data::Boolean(state));
|
||||
self
|
||||
}
|
||||
|
||||
|
|
@ -41,11 +41,11 @@ impl Cmd {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_str(&self, name: &str) -> Option<&str> { self.args.get(name).and_then(Arg::as_str) }
|
||||
pub fn get_str(&self, name: &str) -> Option<&str> { self.args.get(name).and_then(Data::as_str) }
|
||||
|
||||
#[inline]
|
||||
pub fn get_bool(&self, name: &str) -> bool {
|
||||
self.args.get(name).and_then(Arg::as_bool).unwrap_or(false)
|
||||
self.args.get(name).and_then(Data::as_bool).unwrap_or(false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -55,19 +55,19 @@ impl Cmd {
|
|||
|
||||
#[inline]
|
||||
pub fn take_first_str(&mut self) -> Option<String> {
|
||||
if let Some(Arg::String(s)) = self.args.remove("0") { Some(s) } else { None }
|
||||
if let Some(Data::String(s)) = self.args.remove("0") { Some(s) } else { None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn take_name_str(&mut self, name: &str) -> Option<String> {
|
||||
if let Some(Arg::String(s)) = self.args.remove(name) { Some(s) } else { None }
|
||||
if let Some(Data::String(s)) = self.args.remove(name) { Some(s) } else { None }
|
||||
}
|
||||
|
||||
pub fn shallow_clone(&self) -> Self {
|
||||
let args = self
|
||||
.args
|
||||
.iter()
|
||||
.filter_map(|(k, v)| v.as_str().map(|s| (k.clone(), Arg::String(s.to_owned()))))
|
||||
.filter_map(|(k, v)| v.as_str().map(|s| (k.clone(), Data::String(s.to_owned()))))
|
||||
.collect();
|
||||
|
||||
Self { name: self.name.clone(), args, data: None }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::bail;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::OrderedFloat;
|
||||
|
|
@ -8,16 +7,16 @@ use crate::OrderedFloat;
|
|||
// --- Arg
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum Arg {
|
||||
pub enum Data {
|
||||
Nil,
|
||||
Boolean(bool),
|
||||
Integer(i64),
|
||||
Number(f64),
|
||||
String(String),
|
||||
Table(HashMap<ArgKey, Arg>),
|
||||
Table(HashMap<DataKey, Data>),
|
||||
}
|
||||
|
||||
impl Arg {
|
||||
impl Data {
|
||||
#[inline]
|
||||
pub fn as_bool(&self) -> Option<bool> {
|
||||
match self {
|
||||
|
|
@ -41,7 +40,7 @@ impl Arg {
|
|||
|
||||
let mut map = HashMap::with_capacity(table.len());
|
||||
for pair in table {
|
||||
if let (ArgKey::String(k), Self::String(v)) = pair {
|
||||
if let (DataKey::String(k), Self::String(v)) = pair {
|
||||
map.insert(k, v);
|
||||
}
|
||||
}
|
||||
|
|
@ -52,7 +51,7 @@ impl Arg {
|
|||
// --- Key
|
||||
#[derive(Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ArgKey {
|
||||
pub enum DataKey {
|
||||
Nil,
|
||||
Boolean(bool),
|
||||
Integer(i64),
|
||||
|
|
@ -60,17 +59,7 @@ pub enum ArgKey {
|
|||
String(String),
|
||||
}
|
||||
|
||||
impl TryInto<ArgKey> for Arg {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_into(self) -> Result<ArgKey, Self::Error> {
|
||||
Ok(match self {
|
||||
Self::Nil => ArgKey::Nil,
|
||||
Self::Boolean(v) => ArgKey::Boolean(v),
|
||||
Self::Integer(v) => ArgKey::Integer(v),
|
||||
Self::Number(v) => ArgKey::Number(OrderedFloat::new(v)),
|
||||
Self::String(v) => ArgKey::String(v),
|
||||
Self::Table(_) => bail!("table is not supported"),
|
||||
})
|
||||
}
|
||||
impl DataKey {
|
||||
#[inline]
|
||||
pub fn is_numeric(&self) -> bool { matches!(self, Self::Integer(_) | Self::Number(_)) }
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
#![allow(clippy::module_inception)]
|
||||
|
||||
mod arg;
|
||||
mod cmd;
|
||||
mod data;
|
||||
mod event;
|
||||
mod render;
|
||||
|
||||
pub use arg::*;
|
||||
pub use cmd::*;
|
||||
pub use data::*;
|
||||
pub use event::*;
|
||||
pub use render::*;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue