pub(self) use std::path::{Path, PathBuf};
pub(self) use structopt::StructOpt;
pub(self) use crate::{utils, Error, Result, State};
#[cfg(any(
feature = "jsonschema",
feature = "jsonschema-valid",
feature = "valico",
))]
pub(self) use crate::{CompiledSchema, Standard, Validator};
#[cfg(any(
feature = "jsonschema",
feature = "jsonschema-valid",
feature = "valico",
feature = "infers",
))]
pub(self) use crate::Format;
pub type CmdResult = Result<u32>;
#[cfg(feature = "http_req")]
pub(self) use crate::Uri;
const LOG_LEVELS: &[&str] = &["error", "warn", "info", "debug", "trace"];
macro_rules! decl_commands {
($(
$(#[$attr:meta])*
$type:ident $name:ident;
)*) => {
$(
$(#[$attr])*
mod $name;
)*
#[derive(StructOpt, Debug)]
pub enum Command {
$(
$(#[$attr])*
$type($name::Command),
)*
}
impl Command {
pub fn run(&self, args: &Args, state: &State) -> CmdResult {
#[allow(unused_doc_comments)]
match self {
$(
$(#[$attr])*
Self::$type(cmd_args) => cmd_args.run(args, state),
)*
}
}
}
};
}
decl_commands! {
#[cfg(feature = "schemastore")]
Search search;
#[cfg(feature = "schemastore")]
Retrieve retrieve;
#[cfg(feature = "infers")]
Infer infer;
#[cfg(any(
feature = "jsonschema",
feature = "jsonschema-valid",
feature = "valico"
))]
Validate validate;
}
#[derive(StructOpt, Debug)]
pub struct Args {
#[structopt(short = "l", long, env, default_value = "warn", possible_values = LOG_LEVELS)]
pub log_level: String,
#[structopt(short, long)]
pub verbose: bool,
#[structopt(short, long)]
pub quiet: bool,
#[structopt(short = "F", long)]
pub force: bool,
#[cfg(feature = "cache")]
#[structopt(short = "c", long, env)]
pub cache_dir: Option<PathBuf>,
#[cfg(feature = "cache")]
#[structopt(short = "x", long, env)]
pub no_cache: bool,
#[cfg(feature = "schemastore")]
#[structopt(
short = "U",
long,
env,
default_value = "https://www.schemastore.org/api/json/catalog.json"
)]
pub catalog_url: Uri,
#[structopt(subcommand)]
pub command: Command,
}
impl Args {
pub fn run(&self, state: &State) -> CmdResult {
self.command.run(self, state)
}
pub fn check_output_file(&self, path: impl AsRef<Path>) -> Result<()> {
let path = path.as_ref();
if path.is_dir() {
log::error!(
"Output path '{}' is directory and cannot be overwitten in any case",
path.display()
);
return Err(Error::Conflict);
} else if path.is_file() && !self.force {
log::error!(
"Output file '{}' already exists and wont be overwritten. Use -f option to force overwriting",
path.display()
);
return Err(Error::Conflict);
}
Ok(())
}
}