use std::{fmt, path::PathBuf};
use console::style;
use ocpi_tariffs::{cdr, guess, json, schema, tariff, warning, Versioned as _};
use crate::{load_object_file, load_object_from_stdin, print, Error, ObjectKind};
#[derive(clap::Parser)]
pub struct Command {
#[command(flatten)]
args: Arguments,
}
#[derive(clap::Args)]
struct Arguments {
#[arg(short = 't', long = "type")]
kind: ObjectKind,
#[arg(short = 'f', long)]
file: Option<PathBuf>,
#[arg(long)]
validate: bool,
}
impl fmt::Display for ObjectKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ObjectKind::Cdr => f.write_str("CDR"),
ObjectKind::Tariff => f.write_str("tariff"),
}
}
}
struct Outcome {
object_kind: ObjectKind,
version: guess::Version<ocpi_tariffs::Version, ()>,
warnings: Option<warning::Set<schema::Warning>>,
}
impl Command {
pub fn run(self) -> Result<(), Error> {
let Self {
args:
Arguments {
kind: object_kind,
file: path,
validate,
},
} = self;
let json = if let Some(path) = path.as_deref() {
load_object_file(path, object_kind)?
} else {
load_object_from_stdin(object_kind)?
};
let outcome = match object_kind {
ObjectKind::Cdr => {
let cdr = json::parse_object(&json)?;
let guess = cdr::infer_version(cdr);
let version = guess.as_version();
let warnings = match (validate, guess) {
(true, guess::Version::Certain(cdr)) => {
let cdr_version = cdr.version();
let (_cdr, warnings) = cdr::build(cdr.into_doc(), cdr_version).into_parts();
Some(warnings)
}
_ => None,
};
Outcome {
object_kind,
version,
warnings,
}
}
ObjectKind::Tariff => {
let tariff = json::parse_object(&json)?;
let guess = tariff::infer_version(tariff);
let version = guess.as_version();
let warnings = match (validate, guess) {
(true, guess::Version::Certain(tariff)) => {
let tariff_version = tariff.version();
let (_tariff, warnings) =
tariff::build(tariff.into_doc(), tariff_version).into_parts();
Some(warnings)
}
_ => None,
};
Outcome {
object_kind,
version,
warnings,
}
}
};
let Outcome {
object_kind,
warnings,
version,
} = outcome;
if let Some(warnings) = warnings {
print::warning_set("version guessing", &warnings);
}
print_version(object_kind, &version);
Ok(())
}
}
fn print_version(object_kind: ObjectKind, version: &guess::Version<ocpi_tariffs::Version, ()>) {
match version {
guess::Version::Uncertain(()) => {
eprintln!(
"Unable to guess the version of the given {} JSON",
style(object_kind).green()
);
}
guess::Version::Certain(version) => {
println!("{version}");
}
}
}