use anyhow::Result;
use clap::{Args, Subcommand};
use clap_stdin::FileOrStdin;
use serde_json::json;
use snarkvm::synthesizer::Program;
use crate::Network;
pub mod cost;
#[derive(Debug, Subcommand)]
pub enum ProgramCommand<N: Network> {
Id(ProgramInfo<N>),
#[clap(alias = "fn")]
Functions(ProgramInfo<N>),
Imports(ProgramInfo<N>),
Cost(cost::CostCommand<N>),
}
impl<N: Network> ProgramCommand<N> {
pub fn parse(self) -> Result<()> {
match self {
ProgramCommand::Id(ProgramInfo { program, json }) => {
if json {
println!("{}", serde_json::to_string(&program.contents()?.id())?);
} else {
println!("{}", program.contents()?.id());
}
Ok(())
}
ProgramCommand::Functions(ProgramInfo { program, json }) => {
let program = program.contents()?;
if json {
let mut functions = indexmap::IndexMap::new();
for (id, function) in program.functions() {
functions.insert(
id,
json!({
"inputs": function.input_types(),
"outputs": function.output_types(),
}),
);
}
println!("{}", serde_json::to_string(&functions)?);
} else {
for (id, function) in program.functions() {
println!("name: {id}");
println!("inputs:");
for input in function.input_types() {
println!(" {input}");
}
println!("outputs:");
for output in &function.output_types() {
println!(" {output}");
}
println!();
}
}
Ok(())
}
ProgramCommand::Imports(ProgramInfo { program, json }) => {
let program = program.contents()?;
if json {
println!(
"{}",
serde_json::to_string(&program.imports().keys().collect::<Vec<_>>())?
);
} else {
for (id, _import) in program.imports() {
println!("{id}");
}
}
Ok(())
}
ProgramCommand::Cost(command) => {
println!("{}", command.parse()?);
Ok(())
}
}
}
}
#[derive(Debug, Args)]
pub struct ProgramInfo<N: Network> {
pub program: FileOrStdin<Program<N>>,
#[clap(long, short)]
pub json: bool,
}