1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
use anyhow::bail;
use mlua::{Table, Value};
use tokio::sync::oneshot;
use yazi_shared::event::Cmd;

use crate::ValueSendable;

pub struct Opt {
	pub name: String,
	pub sync: bool,
	pub data: OptData,
}

#[derive(Default)]
pub struct OptData {
	pub args: Vec<ValueSendable>,
	pub cb:   Option<Box<dyn FnOnce(Table) -> mlua::Result<Value> + Send>>,
	pub tx:   Option<oneshot::Sender<ValueSendable>>,
}

impl TryFrom<Cmd> for Opt {
	type Error = anyhow::Error;

	fn try_from(mut c: Cmd) -> Result<Self, Self::Error> {
		let Some(name) = c.take_first().filter(|s| !s.is_empty()) else {
			bail!("invalid plugin name");
		};

		let mut data: OptData = c.take_data().unwrap_or_default();

		if let Some(args) = c.named.get("args") {
			data.args = shell_words::split(args)?
				.into_iter()
				.map(|s| ValueSendable::String(s.into_bytes()))
				.collect();
		}

		Ok(Self { name, sync: c.named.contains_key("sync"), data })
	}
}