use std::{fs::File, io::Read, path::Path};
use either::Either;
use tyml_core::{header::TymlHeader, TymlContext};
use tyml_diagnostic::message::{get_text, Lang};
use tyml_generator::registry::STYLE_REGISTRY;
use tyml_source::SourceCode;
#[tokio::main]
async fn main() -> Result<(), String> {
let args = std::env::args().collect::<Vec<_>>();
if args.len() < 2 {
return Err(get_text("binary.message.no_file_specified", Lang::system()));
}
let mut file = File::open(&args[1])
.map_err(|_| get_text("binary.message.failed_to_read_file", Lang::system()))?;
let mut source = String::new();
file.read_to_string(&mut source)
.map_err(|_| get_text("binary.message.failed_to_read_file", Lang::system()))?;
let Some(header) = TymlHeader::parse(&source).await else {
return Err(get_text("binary.message.no_header_found", Lang::system()));
};
if let Some(Err(error)) = &header.style {
return Err(
get_text("binary.message.header_var_lookup_error", Lang::system())
.replace("%0", &error.var_name),
);
}
if let Err(error) = &header.tyml {
match error {
Either::Left(lookup_error) => {
return Err(
get_text("binary.message.header_var_lookup_error", Lang::system())
.replace("%0", &lookup_error.var_name),
);
}
Either::Right(error) => {
return Err(
get_text("binary.message.failed_to_download_tyml", Lang::system())
.replace("%0", error.as_str()),
)
}
}
}
let style = match &header.style {
Some(style) => style.as_ref().unwrap().as_str(),
None => args[1].split(".").last().unwrap(),
};
let tyml = header.tyml.unwrap();
let Some(language) = STYLE_REGISTRY.resolve(style) else {
return Err(
get_text("binary.message.header_no_style_found", Lang::system()).replace("%0", style),
);
};
let mut file = File::open(tyml.as_str()).map_err(|_| {
get_text("binary.message.header_no_tyml_found", Lang::system()).replace("%0", tyml.as_str())
})?;
if !file
.metadata()
.map(|metadata| metadata.is_file())
.unwrap_or(false)
{
return Err(
get_text("binary.message.header_tyml_is_not_file", Lang::system())
.replace("%0", tyml.as_str()),
);
}
let mut tyml_source = String::new();
file.read_to_string(&mut tyml_source).map_err(|_| {
get_text("binary.message.failed_to_read_tyml", Lang::system()).replace("%0", tyml.as_str())
})?;
let tyml = TymlContext::new(SourceCode::new(tyml, tyml_source))
.parse()
.ml_parse_and_validate(
&language,
&SourceCode::new(
Path::new(args[1].as_str())
.file_name()
.unwrap()
.to_string_lossy()
.to_string(),
source,
),
None,
None,
);
tyml.print_tyml_error(Lang::system());
tyml.print_ml_parse_error(Lang::system());
tyml.print_ml_validate_error(Lang::system());
if tyml.has_tyml_error() || tyml.has_ml_parse_error() || tyml.has_ml_validate_error() {
return Err(
get_text("binary.message.has_error", Lang::system()).replace("%0", args[1].as_str())
);
}
Ok(())
}