ocpi_tariffs_cli/
guess_version.rs1use std::{fmt, path::PathBuf};
4
5use console::style;
6use ocpi_tariffs::{cdr, guess, json, schema, tariff, warning, Versioned as _};
7
8use crate::{load_object_file, load_object_from_stdin, print, Error, ObjectKind};
9
10#[derive(clap::Parser)]
12pub struct Command {
13 #[command(flatten)]
15 args: Arguments,
16}
17
18#[derive(clap::Args)]
20struct Arguments {
21 #[arg(short = 't', long = "type")]
23 kind: ObjectKind,
24
25 #[arg(short = 'f', long)]
27 file: Option<PathBuf>,
28
29 #[arg(long)]
31 validate: bool,
32}
33
34impl fmt::Display for ObjectKind {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 match self {
37 ObjectKind::Cdr => f.write_str("CDR"),
38 ObjectKind::Tariff => f.write_str("tariff"),
39 }
40 }
41}
42
43struct Outcome {
45 object_kind: ObjectKind,
47
48 version: guess::Version<ocpi_tariffs::Version, ()>,
50
51 warnings: Option<warning::Set<schema::Warning>>,
56}
57
58impl Command {
59 pub fn run(self) -> Result<(), Error> {
61 let Self {
62 args:
63 Arguments {
64 kind: object_kind,
65 file: path,
66 validate,
67 },
68 } = self;
69
70 let json = if let Some(path) = path.as_deref() {
71 load_object_file(path, object_kind)?
72 } else {
73 load_object_from_stdin(object_kind)?
74 };
75
76 let outcome = match object_kind {
77 ObjectKind::Cdr => {
78 let cdr = json::parse_object(&json)?;
79 let guess = cdr::infer_version(cdr);
80 let version = guess.as_version();
81
82 let warnings = match (validate, guess) {
84 (true, guess::Version::Certain(cdr)) => {
85 let cdr_version = cdr.version();
86 let (_cdr, warnings) = cdr::build(cdr.into_doc(), cdr_version).into_parts();
87 Some(warnings)
88 }
89 _ => None,
90 };
91
92 Outcome {
93 object_kind,
94 version,
95 warnings,
96 }
97 }
98 ObjectKind::Tariff => {
99 let tariff = json::parse_object(&json)?;
100 let guess = tariff::infer_version(tariff);
101 let version = guess.as_version();
102
103 let warnings = match (validate, guess) {
105 (true, guess::Version::Certain(tariff)) => {
106 let tariff_version = tariff.version();
107 let (_tariff, warnings) =
108 tariff::build(tariff.into_doc(), tariff_version).into_parts();
109 Some(warnings)
110 }
111 _ => None,
112 };
113
114 Outcome {
115 object_kind,
116 version,
117 warnings,
118 }
119 }
120 };
121
122 let Outcome {
123 object_kind,
124 warnings,
125 version,
126 } = outcome;
127
128 if let Some(warnings) = warnings {
129 print::warning_set("version guessing", &warnings);
130 }
131
132 print_version(object_kind, &version);
133
134 Ok(())
135 }
136}
137
138fn print_version(object_kind: ObjectKind, version: &guess::Version<ocpi_tariffs::Version, ()>) {
140 match version {
141 guess::Version::Uncertain(()) => {
142 eprintln!(
143 "Unable to guess the version of the given {} JSON",
144 style(object_kind).green()
145 );
146 }
147 guess::Version::Certain(version) => {
148 println!("{version}");
149 }
150 }
151}