use crate::common::report::report_error;
use enumset::EnumSet;
use enumset::EnumSetType;
use yash_env::Env;
use yash_env::semantics::Field;
#[cfg(all(doc, unix))]
use yash_env::system::real::RealSystem;
use yash_env::system::resource::SetRlimit;
use yash_env::system::{
Close, Dup, Exec, Exit, Fcntl, Fork, Fstat, GetCwd, GetPid, IsExecutableFile, Isatty, Open,
SendSignal, SetPgid, ShellPath, Sigaction, Sigmask, Signals, Sysconf, TcSetPgrp, Wait, Write,
};
#[derive(Clone, Copy, Debug, EnumSetType, Eq, Hash, PartialEq)]
#[enumset(no_super_impls)]
#[non_exhaustive]
pub enum Category {
Alias,
Builtin,
ExternalUtility,
Function,
Keyword,
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
#[non_exhaustive]
pub struct Search {
pub standard_path: bool,
pub categories: EnumSet<Category>,
}
impl Search {
#[must_use]
pub fn default_for_invoke() -> Self {
Self {
standard_path: false,
categories: Category::Builtin | Category::ExternalUtility,
}
}
#[must_use]
pub fn default_for_identify() -> Self {
Self {
standard_path: false,
categories: EnumSet::all(),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Invoke {
pub fields: Vec<Field>,
pub search: Search,
}
impl Default for Invoke {
fn default() -> Self {
Self {
fields: Vec::default(),
search: Search::default_for_invoke(),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Identify {
pub names: Vec<Field>,
pub search: Search,
pub verbose: bool,
}
impl Default for Identify {
fn default() -> Self {
Self {
names: Vec::default(),
search: Search::default_for_identify(),
verbose: false,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum Command {
Invoke(Invoke),
Identify(Identify),
}
impl From<Invoke> for Command {
fn from(invoke: Invoke) -> Self {
Self::Invoke(invoke)
}
}
impl From<Identify> for Command {
fn from(identify: Identify) -> Self {
Self::Identify(identify)
}
}
impl Command {
pub async fn execute<S>(self, env: &mut Env<S>) -> crate::Result
where
S: Close
+ Dup
+ Exec
+ Exit
+ Fcntl
+ Fork
+ Fstat
+ GetCwd
+ GetPid
+ IsExecutableFile
+ Isatty
+ Open
+ SendSignal
+ SetPgid
+ SetRlimit
+ ShellPath
+ Sigaction
+ Sigmask
+ Signals
+ Sysconf
+ TcSetPgrp
+ Wait
+ Write
+ 'static,
{
match self {
Self::Invoke(invoke) => invoke.execute(env).await,
Self::Identify(identify) => identify.execute(env).await,
}
}
}
pub mod identify;
mod invoke;
pub mod search;
pub mod syntax;
pub async fn main<S>(env: &mut Env<S>, args: Vec<Field>) -> crate::Result
where
S: Close
+ Dup
+ Exec
+ Exit
+ Fcntl
+ Fork
+ Fstat
+ GetCwd
+ GetPid
+ IsExecutableFile
+ Isatty
+ Open
+ SendSignal
+ SetPgid
+ SetRlimit
+ ShellPath
+ Sigaction
+ Sigmask
+ Signals
+ Sysconf
+ TcSetPgrp
+ Wait
+ Write
+ 'static,
{
match syntax::parse(env, args) {
Ok(command) => command.execute(env).await,
Err(error) => report_error(env, &error).await,
}
}