use std::path::PathBuf;
use std::process::ExitCode;
use anyhow::{Context, Result};
use clap::{Parser, Subcommand};
use serde_json::Value;
use crate::validate_value;
#[derive(Debug, Parser)]
#[command(name = "ferrocv", version, about, long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Debug, Subcommand)]
enum Commands {
Validate {
path: Option<PathBuf>,
},
}
pub fn run() -> Result<ExitCode> {
let cli = Cli::parse();
match cli.command {
Commands::Validate { path } => run_validate(path.as_deref()),
}
}
fn run_validate(path: Option<&std::path::Path>) -> Result<ExitCode> {
let input =
match path {
Some(p) => std::fs::read_to_string(p)
.with_context(|| format!("failed to read {}", p.display()))?,
None => std::io::read_to_string(std::io::stdin())
.context("failed to read JSON from stdin")?,
};
let value: Value = match serde_json::from_str(&input) {
Ok(v) => v,
Err(err) => {
eprintln!("error: {err}");
return Ok(ExitCode::from(2));
}
};
match validate_value(&value) {
Ok(()) => Ok(ExitCode::SUCCESS),
Err(errors) => {
for err in errors {
eprintln!("{err}");
}
Ok(ExitCode::from(1))
}
}
}