sovereign-addr / src /cli.rs
SNAPKITTYWEST's picture
push from SNAPKITTYWEST/sovereign-addr
103262d verified
Raw
History Blame Contribute Delete
4.06 kB
// cli.rs — CLI commands for sovereign addressing
//
// Commands: encode, bytes, receipt, verify
use clap::{Parser, Subcommand};
use std::fs;
use std::io::{self, Read};
use crate::{sovereign_address, sovereign_address_bytes, worm_receipt, verify_address, verify_receipt};
#[derive(Parser)]
#[command(name = "snapaddr", about = "SnapKitty Sovereign Addressing")]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
}
#[derive(Subcommand)]
pub enum Commands {
/// Compute sovereign address of a JSON value
Encode {
/// JSON file path (reads stdin if not provided)
#[arg(value_name = "FILE")]
file: Option<String>,
},
/// Compute raw address bytes
Bytes {
/// JSON file path
#[arg(value_name = "FILE")]
file: Option<String>,
},
/// Generate WORM receipt
Receipt {
/// JSON file path
#[arg(value_name = "FILE")]
file: Option<String>,
},
/// Verify address or receipt
Verify {
/// JSON file path
#[arg(value_name = "FILE")]
file: String,
/// Expected address (for address verification)
#[arg(long)]
address: Option<String>,
},
/// Validate JSON admissibility
Validate {
/// JSON file path
#[arg(value_name = "FILE")]
file: Option<String>,
},
}
/// Read JSON from file or stdin.
fn read_json(file: Option<&str>) -> Result<serde_json::Value, Box<dyn std::error::Error>> {
let input = match file {
Some(path) => fs::read_to_string(path)?,
None => {
let mut buf = String::new();
io::stdin().read_to_string(&mut buf)?;
buf
}
};
Ok(serde_json::from_str(&input)?)
}
/// Run the CLI.
pub fn run() -> Result<(), Box<dyn std::error::Error>> {
let cli = Cli::parse();
match cli.command {
Commands::Encode { file } => {
let value = read_json(file.as_deref())?;
let addr = sovereign_address(&value)?;
println!("{}", addr);
}
Commands::Bytes { file } => {
let value = read_json(file.as_deref())?;
let bytes = sovereign_address_bytes(&value)?;
for b in &bytes {
print!("{:02x}", b);
}
println!();
}
Commands::Receipt { file } => {
let value = read_json(file.as_deref())?;
let receipt = worm_receipt(&value)?;
println!("{}", serde_json::to_string_pretty(&receipt)?);
}
Commands::Verify { file, address } => {
let value = read_json(Some(&file))?;
if let Some(addr) = address {
let ok = verify_address(&value, &addr)?;
if ok {
println!("✓ Address verified");
} else {
println!("✗ Address mismatch");
std::process::exit(1);
}
} else {
// Verify receipt
let receipt = worm_receipt(&value)?;
let ok = verify_receipt(&receipt)?;
if ok {
println!("✓ Receipt verified");
println!("{}", serde_json::to_string_pretty(&receipt)?);
} else {
println!("✗ Receipt verification failed");
std::process::exit(1);
}
}
}
Commands::Validate { file } => {
let value = read_json(file.as_deref())?;
let result = crate::admissibility::validate_admissible(&value);
match result {
Ok(()) => println!("✓ JSON is admissible"),
Err(e) => {
println!("✗ Not admissible: {}", e);
std::process::exit(1);
}
}
}
}
Ok(())
}