use crate::common::report::{merge_reports, report, report_simple};
use yash_env::Env;
use yash_env::semantics::ExitStatus;
use yash_env::semantics::Field;
pub mod assigning;
pub mod input;
pub mod syntax;
pub const EXIT_STATUS_SUCCESS: ExitStatus = ExitStatus(0);
pub const EXIT_STATUS_EOF: ExitStatus = ExitStatus(1);
pub const EXIT_STATUS_ASSIGN_ERROR: ExitStatus = ExitStatus(2);
pub const EXIT_STATUS_READ_ERROR: ExitStatus = ExitStatus(3);
pub const EXIT_STATUS_SYNTAX_ERROR: ExitStatus = ExitStatus(4);
#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub struct Command {
pub delimiter: u8,
pub is_raw: bool,
pub variables: Vec<Field>,
pub last_variable: Field,
}
pub async fn main(env: &mut Env, args: Vec<Field>) -> crate::Result {
let command = match syntax::parse(env, args) {
Ok(command) => command,
Err(error) => return report(env, &error, EXIT_STATUS_SYNTAX_ERROR).await,
};
let (input, newline_found) = match input::read(env, command.delimiter, command.is_raw).await {
Ok(input) => input,
Err(error) => return report(env, &error, EXIT_STATUS_READ_ERROR).await,
};
if input.iter().any(|c| c.value == '\0') {
return report_simple(env, "input contains a nul byte", EXIT_STATUS_READ_ERROR).await;
}
let errors = assigning::assign(env, &input, command.variables, command.last_variable);
match merge_reports(&errors) {
None if newline_found => EXIT_STATUS_SUCCESS.into(),
None => EXIT_STATUS_EOF.into(),
Some(report) => self::report(env, report, EXIT_STATUS_ASSIGN_ERROR).await,
}
}