jsonc_tools 0.0.1

jsonc_tools: Tools to deal with `jsonc` files. See, [JSON with Comments](https://code.visualstudio.com/docs/languages/json#_json-with-comments) and [jsonc](https://komkom.github.io/) (A Json like file format with comments). See, [User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings) and [Settings - vscode](https://vscode.readthedocs.io/en/latest/getstarted/settings/) for example files.
Documentation
// use std::path::PathBuf;
use structopt::StructOpt;

const PKG_NAME: &str = std::env!("CARGO_PKG_NAME");
const PKG_VERSION: &str = std::env!("CARGO_PKG_VERSION");
const PKG_DESCRIPTION: &str = std::env!("CARGO_PKG_DESCRIPTION");
const _PKG_REPOSITORY: &str = std::env!("CARGO_PKG_REPOSITORY");

// Our CLI arguments. (help and version are automatically generated)
// Documentation on how to use:
// https://docs.rs/structopt/0.3.17/structopt/
// https://docs.rs/structopt/0.3.17
#[derive(
    StructOpt, Debug, Default, Clone, Hash, PartialEq, PartialOrd, Eq, Ord,
)]
#[structopt(
  name = PKG_NAME,
  about = PKG_DESCRIPTION,
  version = PKG_VERSION,
  global_settings = &[
        structopt::clap::AppSettings::ColoredHelp,
        structopt::clap::AppSettings::VersionlessSubcommands,
        structopt::clap::AppSettings::ArgRequiredElseHelp,
        ])]
pub struct Cli {
    /// Log Level: The level to configure the logger.
    #[structopt(
        short,
        long,
        default_value = LogLevel::default().as_str(),
        possible_values = &LogLevel::possible_values(),
    )]
    pub log_level: LogLevel,

    /// Activate dry run mode: Print the ouput to stdout (standard output), but do not overwrite existing file.
    #[structopt(short = "r", long)]
    pub dry_run: bool,

    /// Input file: The file to use.
    #[structopt(short, long, parse(from_os_str))]
    pub input: std::path::PathBuf,

    /// Output file: stdout if not present.
    #[structopt(long, parse(from_os_str))]
    pub output: Option<std::path::PathBuf>,

    /// Output type: Where to write the output: to `stdout` or `file`.
    #[structopt(long)]
    pub out_type: String,

    /// File name: Only required when `out-type` is set to `file`.
    #[structopt(short, long, name = "FILE", required_if("out-type", "file"))]
    pub file_name: Option<String>,
}

#[derive(StructOpt, Debug, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)]
pub enum LogLevel {
    Error,
    Warn,
    Info,
    Debug,
    Trace,
}

impl std::str::FromStr for LogLevel {
    type Err = Box<dyn std::error::Error>;

    fn from_str(s: &str) -> Result<LogLevel, Self::Err> {
        use LogLevel::*;
        match s {
            "error" => Ok(Error),
            "warn" => Ok(Warn),
            "info" => Ok(Info),
            "debug" => Ok(Debug),
            "trace" => Ok(Trace),
            log_level => {
                Err(format!("error: invalid log_level={}", log_level).into())
            }
        }
    }
}

impl std::default::Default for LogLevel {
    fn default() -> Self {
        LogLevel::Info
    }
}

impl LogLevel {
    pub fn as_str(&self) -> &'static str {
        use LogLevel::*;
        match self {
            Error => "error",
            Warn => "warn",
            Info => "info",
            Debug => "debug",
            Trace => "trace",
        }
    }

    pub fn possible_values() -> &'static [&'static str] {
        &["error", "warn", "info", "debug", "trace"]
    }
}

pub fn new() -> Cli {
    Cli::from_args()
}

impl Cli {
    pub fn new() -> Self {
        Cli::from_args()
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }

    use pretty_assertions::assert_eq;

    #[test]
    fn it_works_pretty_assertions() {
        assert_eq!(2 + 2, 4);
    }
}