use std::path::PathBuf;
use anyhow::{Context, Result, anyhow};
use clap::{Parser, Subcommand, ValueEnum};
use eros_nft::{
PersonaDraft, PersonaManifest, json_schema_draft, json_schema_manifest, list_samples,
load_sample,
};
#[derive(Parser)]
#[command(
name = "eros-nft",
version,
about = "Validate and inspect eros-nft documents."
)]
struct Cli {
#[command(subcommand)]
cmd: Cmd,
}
#[derive(Subcommand)]
enum Cmd {
Validate {
path: PathBuf,
},
Schema {
#[command(subcommand)]
action: SchemaAction,
},
Sample {
#[command(subcommand)]
action: SampleAction,
},
}
#[derive(Subcommand)]
enum SchemaAction {
Export {
kind: SchemaKind,
},
}
#[derive(ValueEnum, Clone)]
enum SchemaKind {
Draft,
Manifest,
}
#[derive(Subcommand)]
enum SampleAction {
List,
Show {
slug: String,
},
}
fn main() -> Result<()> {
let cli = Cli::parse();
match cli.cmd {
Cmd::Validate { path } => cmd_validate(path),
Cmd::Schema {
action: SchemaAction::Export { kind },
} => {
match kind {
SchemaKind::Draft => println!("{}", json_schema_draft()),
SchemaKind::Manifest => println!("{}", json_schema_manifest()),
}
Ok(())
}
Cmd::Sample {
action: SampleAction::List,
} => {
for s in list_samples() {
println!("{s}");
}
Ok(())
}
Cmd::Sample {
action: SampleAction::Show { slug },
} => {
let (draft, manifest) =
load_sample(&slug).ok_or_else(|| anyhow!("unknown sample: {slug}"))?;
println!("=== draft.json ===");
println!("{}", serde_json::to_string_pretty(&draft)?);
println!("\n=== manifest.json ===");
println!("{}", serde_json::to_string_pretty(&manifest)?);
Ok(())
}
}
}
fn cmd_validate(path: PathBuf) -> Result<()> {
let bytes = std::fs::read(&path).with_context(|| format!("reading {path:?}"))?;
let value: serde_json::Value =
serde_json::from_slice(&bytes).with_context(|| format!("parsing JSON from {path:?}"))?;
if value.get("persona_id").is_some() {
let m: PersonaManifest = serde_json::from_value(value).context("parsing as Manifest")?;
m.validate().context("validating Manifest")?;
println!("ok: PersonaManifest {path:?}");
} else {
let d: PersonaDraft = serde_json::from_value(value).context("parsing as Draft")?;
d.validate().context("validating Draft")?;
println!("ok: PersonaDraft {path:?}");
}
Ok(())
}