mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-22 15:21:04 +00:00
239 lines
5.5 KiB
Rust
239 lines
5.5 KiB
Rust
use std::{borrow::Cow, ffi::OsString};
|
|
|
|
use anyhow::{Result, bail};
|
|
use clap::{Parser, Subcommand};
|
|
use yazi_shared::id::Id;
|
|
|
|
#[derive(Parser)]
|
|
#[command(name = "Ya", about, long_about = None)]
|
|
pub(super) struct Args {
|
|
#[command(subcommand)]
|
|
pub(super) command: Command,
|
|
|
|
/// Print version
|
|
#[arg(short = 'V', long)]
|
|
pub(super) version: bool,
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
pub(super) enum Command {
|
|
/// Emit an action to be executed by the current instance.
|
|
Emit(CommandEmit),
|
|
/// Emit an action to be executed by the specified instance.
|
|
EmitTo(CommandEmitTo),
|
|
/// Execute an action on the current instance and print its result.
|
|
Exec(CommandExec),
|
|
/// Manage packages.
|
|
#[command(subcommand)]
|
|
Pkg(CommandPkg),
|
|
/// Publish a message to the current instance.
|
|
Pub(CommandPub),
|
|
/// Publish a message to the specified instance.
|
|
PubTo(CommandPubTo),
|
|
/// Subscribe to messages from all remote instances.
|
|
Sub(CommandSub),
|
|
/// Manage the cache.
|
|
#[command(subcommand)]
|
|
Cache(CommandCache),
|
|
/// Print environment and configuration information.
|
|
Env,
|
|
}
|
|
|
|
#[derive(clap::Args)]
|
|
pub(super) struct CommandEmit {
|
|
/// Name of the action.
|
|
pub(super) name: String,
|
|
/// Arguments of the action.
|
|
#[arg(allow_hyphen_values = true, trailing_var_arg = true)]
|
|
pub(super) args: Vec<OsString>,
|
|
}
|
|
|
|
#[derive(clap::Args)]
|
|
pub(super) struct CommandEmitTo {
|
|
/// Receiver ID.
|
|
pub(super) receiver: Id,
|
|
/// Name of the action.
|
|
pub(super) name: String,
|
|
/// Arguments of the action.
|
|
#[arg(allow_hyphen_values = true, trailing_var_arg = true)]
|
|
pub(super) args: Vec<OsString>,
|
|
}
|
|
|
|
#[derive(clap::Args)]
|
|
pub(super) struct CommandExec {
|
|
/// Name of the action.
|
|
pub(super) name: String,
|
|
/// Arguments of the action.
|
|
#[arg(allow_hyphen_values = true, trailing_var_arg = true)]
|
|
pub(super) args: Vec<OsString>,
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
pub(super) enum CommandPkg {
|
|
/// Add packages.
|
|
#[command(arg_required_else_help = true)]
|
|
Add {
|
|
/// Packages to add.
|
|
#[arg(index = 1, num_args = 1..)]
|
|
ids: Vec<String>,
|
|
},
|
|
/// Delete packages.
|
|
#[command(arg_required_else_help = true)]
|
|
Delete {
|
|
/// Packages to delete.
|
|
#[arg(index = 1, num_args = 1..)]
|
|
ids: Vec<String>,
|
|
/// Discard local changes made to packages while deleting.
|
|
#[arg(long)]
|
|
discard: bool,
|
|
},
|
|
/// Install all packages.
|
|
Install {
|
|
/// Discard local changes made to packages while installing.
|
|
#[arg(long)]
|
|
discard: bool,
|
|
},
|
|
/// List all packages.
|
|
List,
|
|
/// Upgrade all packages.
|
|
Upgrade {
|
|
/// Packages to upgrade, upgrade all if unspecified.
|
|
#[arg(index = 1, num_args = 0..)]
|
|
ids: Vec<String>,
|
|
/// Discard local changes made to packages while upgrading.
|
|
#[arg(long)]
|
|
discard: bool,
|
|
},
|
|
}
|
|
|
|
#[derive(clap::Args)]
|
|
pub(super) struct CommandPub {
|
|
/// Kind of message.
|
|
#[arg(index = 1)]
|
|
pub(super) kind: String,
|
|
/// Send the message with a string body.
|
|
#[arg(long)]
|
|
pub(super) str: Option<String>,
|
|
/// Send the message with a JSON body.
|
|
#[arg(long)]
|
|
pub(super) json: Option<String>,
|
|
/// Send the message as a list of strings.
|
|
#[arg(long, num_args = 0..)]
|
|
pub(super) list: Vec<String>,
|
|
}
|
|
|
|
impl CommandPub {
|
|
#[allow(dead_code)]
|
|
pub(super) fn receiver() -> Result<Id> {
|
|
if let Some(s) = std::env::var("YAZI_PID").ok().filter(|s| !s.is_empty()) {
|
|
Ok(s.parse()?)
|
|
} else {
|
|
bail!("No `YAZI_ID` environment variable found.")
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(clap::Args)]
|
|
pub(super) struct CommandPubTo {
|
|
/// Receiver ID.
|
|
#[arg(index = 1)]
|
|
pub(super) receiver: Id,
|
|
/// Kind of message.
|
|
#[arg(index = 2)]
|
|
pub(super) kind: String,
|
|
/// Send the message with a string body.
|
|
#[arg(long)]
|
|
pub(super) str: Option<String>,
|
|
/// Send the message with a JSON body.
|
|
#[arg(long)]
|
|
pub(super) json: Option<String>,
|
|
/// Send the message as a list of strings.
|
|
#[arg(long, num_args = 0..)]
|
|
pub(super) list: Vec<String>,
|
|
}
|
|
|
|
#[derive(clap::Args)]
|
|
pub(super) struct CommandSub {
|
|
/// Kind of messages to subscribe to, separated by commas if multiple.
|
|
#[arg(index = 1)]
|
|
pub(super) kinds: String,
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
pub(super) enum CommandCache {
|
|
/// Clear the cache directory.
|
|
Clear,
|
|
}
|
|
|
|
// --- Macros
|
|
macro_rules! impl_emit_body {
|
|
($name:ident) => {
|
|
impl $name {
|
|
#[allow(dead_code)]
|
|
pub(super) fn body(self) -> Result<String> {
|
|
#[derive(serde::Serialize)]
|
|
#[serde(untagged)]
|
|
enum Elem {
|
|
Name(String),
|
|
Arg(Vec<u8>),
|
|
}
|
|
|
|
let action: Vec<_> = [Elem::Name(self.name)]
|
|
.into_iter()
|
|
.chain(self.args.into_iter().map(|s| Elem::Arg(s.into_encoded_bytes())))
|
|
.collect();
|
|
Ok(serde_json::to_string(&action)?)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! impl_exec_body {
|
|
($name:ident) => {
|
|
impl $name {
|
|
#[allow(dead_code)]
|
|
pub(super) fn body(self, reply_to: Id) -> Result<String> {
|
|
#[derive(serde::Serialize)]
|
|
#[serde(untagged)]
|
|
enum Elem {
|
|
Id(Id),
|
|
Name(String),
|
|
Arg(Vec<u8>),
|
|
}
|
|
|
|
let action: Vec<_> = [Elem::Id(reply_to), Elem::Name(self.name)]
|
|
.into_iter()
|
|
.chain(self.args.into_iter().map(|s| Elem::Arg(s.into_encoded_bytes())))
|
|
.collect();
|
|
Ok(serde_json::to_string(&action)?)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! impl_pub_body {
|
|
($name:ident) => {
|
|
impl $name {
|
|
#[allow(dead_code)]
|
|
pub(super) fn body(&self) -> Result<Cow<'_, str>> {
|
|
Ok(if let Some(json) = &self.json {
|
|
json.into()
|
|
} else if let Some(str) = &self.str {
|
|
serde_json::to_string(str)?.into()
|
|
} else if !self.list.is_empty() {
|
|
serde_json::to_string(&self.list)?.into()
|
|
} else {
|
|
"".into()
|
|
})
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
impl_emit_body!(CommandEmit);
|
|
impl_emit_body!(CommandEmitTo);
|
|
|
|
impl_exec_body!(CommandExec);
|
|
|
|
impl_pub_body!(CommandPub);
|
|
impl_pub_body!(CommandPubTo);
|