use std::{collections::HashMap, fs};
use clap::Parser;
use miette::{IntoDiagnostic, NamedSource, Report, Result};
use mpl_lang::query::{ParamType, TerminalParamType};
#[derive(Clone, Copy, clap::ValueEnum)]
enum Format {
Json,
Ron,
Debug,
}
#[derive(Parser)]
#[command(name = "mplc")]
#[command(about = "MPL Command Line Interface")]
#[command(version)]
struct Args {
#[command(subcommand)]
command: Command,
}
#[derive(clap::Subcommand)]
enum Command {
Parse {
file: String,
#[arg(short, long, value_enum, default_value = "ron")]
format: Format,
#[arg(short, long)]
output: Option<String>,
},
}
fn main() -> Result<()> {
let args = Args::parse();
match args.command {
Command::Parse {
file,
format,
output,
} => {
let content = fs::read_to_string(&file)
.into_diagnostic()
.map_err(|e| e.context(format!("Failed to read file '{file}'")))?;
let mut system_params = HashMap::new();
system_params.insert(
"__interval".to_string(),
ParamType::Terminal(TerminalParamType::Duration),
);
let (parsed_query, _warnings) =
mpl_lang::compile(&content, system_params).map_err(|e| {
Report::new(e).with_source_code(NamedSource::new(&file, content.clone()))
})?;
let output_str = match format {
Format::Json => serde_json::to_string_pretty(&parsed_query)
.into_diagnostic()
.map_err(|e| e.context("Failed to serialize to JSON"))?,
Format::Ron => {
ron::ser::to_string_pretty(&parsed_query, ron::ser::PrettyConfig::default())
.into_diagnostic()
.map_err(|e| e.context("Failed to serialize to RON"))?
}
Format::Debug => format!("{parsed_query:?}"),
};
match output {
Some(path) => {
fs::write(&path, &output_str)
.into_diagnostic()
.map_err(|e| e.context(format!("Failed to write to '{path}'")))?;
}
None => {
let lang = match format {
Format::Json => "json",
Format::Ron => "ron",
Format::Debug => {
println!("{output_str}");
return Ok(());
}
};
let theme = arborium::theme::builtin::catppuccin_mocha();
let mut hl = arborium::AnsiHighlighter::new(theme);
match hl.highlight(lang, &output_str) {
Ok(colored) => println!("{colored}"),
Err(_) => println!("{output_str}"),
}
}
}
}
}
Ok(())
}