use crate::common::report::report_error;
use enumset::EnumSet;
use enumset::EnumSetType;
use yash_env::Env;
use yash_env::semantics::Field;
#[cfg(doc)]
use yash_env::system::System;
#[cfg(all(doc, unix))]
use yash_env::system::real::RealSystem;
#[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(self, env: &mut Env) -> crate::Result {
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(env: &mut Env, args: Vec<Field>) -> crate::Result {
match syntax::parse(env, args) {
Ok(command) => command.execute(env).await,
Err(error) => report_error(env, &error).await,
}
}