use std::{io::IsTerminal as _, path::PathBuf};
use clap::{Args, Parser};
use console::style;
use ocpi_tariffs::{json, tariff};
use crate::{
load_object_file, load_object_from_stdin,
opts::{FilePath, Version},
print, Error, ObjectKind,
};
const STDIN_NAME: &str = "<stdin>";
#[derive(Parser)]
pub struct Command {
#[command(flatten)]
args: Arguments,
}
#[derive(Args)]
struct Arguments {
#[arg(short = 'o', long, value_enum)]
ocpi_version: Version,
#[arg(long)]
pretty: bool,
#[arg(short = 'f', long)]
file: Option<PathBuf>,
}
impl Command {
pub fn run(self) -> Result<(), Error> {
let Self {
args:
Arguments {
ocpi_version,
pretty,
file: tariff,
},
} = self;
let ocpi_version = ocpi_version.into();
let tariff_file_path = tariff.as_deref().map(FilePath::from_path).transpose()?;
let tariff_name = tariff_file_path
.as_ref()
.map(FilePath::file_name)
.unwrap_or(STDIN_NAME);
eprintln!(
"{} tariff `{}` as version `{}`",
style("Explaining").green().bold(),
style(&tariff_name).blue(),
style(ocpi_version).blue()
);
let tariff_json = if let Some(path) = tariff_file_path.as_ref() {
load_object_file(path, ObjectKind::Tariff)?
} else if std::io::stdin().is_terminal() {
return Err(Error::TariffRequired);
} else {
load_object_from_stdin(ObjectKind::Tariff)?
};
let tariff_doc = json::parse_object(&tariff_json)?;
let (tariff, warnings) = tariff::build(tariff_doc, ocpi_version).into_parts();
print::warning_set("tariff validation", &warnings);
if pretty {
eprintln!("{}", style("# Source Tariff:").green());
eprintln!("{}\n", json::write::Pretty::from_doc(tariff.as_doc()));
}
let (explanation, warnings) = match tariff::explain(&tariff) {
Ok(caveat) => caveat.into_parts(),
Err(error_set) => {
let (error, warnings) = error_set.into_parts();
print::warning_set("the tariff explanation", &warnings);
return Err(Error::Explain(error));
}
};
eprintln!("Completed {} tariff\n", style("explaining").green().bold());
print::warning_set("the tariff explanation", &warnings);
println!("{explanation}");
Ok(())
}
}