#![doc = include_str!("../README.md")]
use lexi_gram::gen_parser::{try_gen_parser, GenParserError};
use lexi_gram::{lexigram_lib, LEXIGRAM_PKG_VERSION, LEXIGRAM_PKG_NAME};
use lexi_gram::lexigram_lib::CollectJoin;
use lexigram_lib::{LIB_PKG_VERSION, LIB_PKG_NAME};
use lexigram_lib::lexigram_core::{CORE_PKG_VERSION, CORE_PKG_NAME};
use lexigram_lib::log::LogStatus;
use crate::arg_opt::{parse_args, ArgOptions, HELP_MESSAGE};
mod arg_opt;
pub const BIN_PKG_NAME: &str = env!("CARGO_PKG_NAME");
pub const BIN_PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
pub enum ExeError {
Help,
Version,
Option(String),
GenParser { source: GenParserError, show_log: bool },
Message(String),
}
#[derive(Clone, Copy, Default, PartialEq, Debug)]
pub enum ExeAnsi {
Off,
#[default] On,
OnPassive,
}
fn main() {
let all_args: Vec<String> = std::env::args().skip(1).collect();
let code = match execute(all_args) {
Ok(message_opt) => {
if let Some(message) = message_opt {
println!("{message}");
}
eprintln!("OK");
0
}
Err(e) => {
match e {
ExeError::Help => {
eprintln!("{HELP_MESSAGE}");
1
}
ExeError::Version => {
eprintln!("Versions:\n- {BIN_PKG_NAME}: {BIN_PKG_VERSION}");
eprintln!("- {CORE_PKG_NAME}: {CORE_PKG_VERSION}");
eprintln!("- {LIB_PKG_NAME}: {LIB_PKG_VERSION}");
eprintln!("- {LEXIGRAM_PKG_NAME}: {LEXIGRAM_PKG_VERSION}");
1
}
ExeError::Option(msg) => {
eprintln!("Error while parsing the command arguments: {msg}");
2
}
ExeError::GenParser { source, .. } => {
eprintln!("Generator error:\n{source}");
3
}
ExeError::Message(s) => {
eprintln!("{s}");
4
}
}
}
};
std::process::exit(code);
}
pub fn execute(all_args: Vec<String>) -> Result<Option<String>, ExeError> {
let (action, arg_options) = parse_args(all_args)?;
let ArgOptions { gen_options, show_log, ansi } = arg_options;
if ansi == ExeAnsi::On {
match enable_ansi_support::enable_ansi_support() {
Ok(()) => {}
Err(e) => return Err(ExeError::Message(format!("ERROR: this console doesn't support ANSI output:\n{e}"))),
}
}
match try_gen_parser(action, gen_options) {
Ok(log) => {
Ok(if show_log {
Some(log.to_string())
} else {
Some(format!("{}{}", log.get_warnings().map(|s| s.to_string()).join("\n"), log.get_totals()))
})
}
Err(source) => {
Err(ExeError::GenParser { source, show_log })
}
}
}