use std::fs::File;
use std::path::{Path, PathBuf};
use hypersonic::{Articles, AuthToken, CallParams, IssueParams, Schema, Stock};
#[derive(Parser)]
pub enum Cmd {
Issue {
schema: PathBuf,
params: PathBuf,
output: Option<PathBuf>,
},
Process {
articles: PathBuf,
stock: Option<PathBuf>,
},
State {
stock: PathBuf,
},
Call {
stock: PathBuf,
call: PathBuf,
},
Export {
stock: PathBuf,
#[clap(short, long)]
terminals: Vec<AuthToken>,
output: PathBuf,
},
Accept {
stock: PathBuf,
input: PathBuf,
},
}
impl Cmd {
pub fn exec(&self) -> anyhow::Result<()> {
match self {
Cmd::Issue { schema, params, output } => issue(schema, params, output.as_deref())?,
Cmd::Process { articles, stock } => process(articles, stock.as_deref())?,
Cmd::State { stock } => state(stock),
Cmd::Call { stock, call: path } => call(stock, path)?,
Cmd::Export { stock, terminals, output } => export(stock, terminals, output)?,
Cmd::Accept { stock, input } => accept(stock, input)?,
}
Ok(())
}
}
fn issue(schema: &Path, form: &Path, output: Option<&Path>) -> anyhow::Result<()> {
let schema = Schema::load(schema)?;
let file = File::open(form)?;
let params = serde_yaml::from_reader::<_, IssueParams>(file)?;
let path = output.unwrap_or(form);
let output = path.with_file_name(&format!("{}.articles", params.name));
let articles = schema.issue::<0>(params);
articles.save(output)?;
Ok(())
}
fn process(articles: &Path, stock: Option<&Path>) -> anyhow::Result<()> {
let path = stock.unwrap_or(articles);
let articles = Articles::<0>::load(articles)?;
Stock::new(articles, path);
Ok(())
}
fn state(path: &Path) {
let stock = Stock::<_, 0>::load(path);
let val = serde_yaml::to_string(&stock.state().main).expect("unable to generate YAML");
println!("{val}");
}
fn call(stock: &Path, form: &Path) -> anyhow::Result<()> {
let mut stock = Stock::<_, 0>::load(stock);
let file = File::open(form)?;
let call = serde_yaml::from_reader::<_, CallParams>(file)?;
let opid = stock.call(call);
println!("Operation ID: {opid}");
Ok(())
}
fn export<'a>(stock: &Path, terminals: impl IntoIterator<Item = &'a AuthToken>, output: &Path) -> anyhow::Result<()> {
let mut stock = Stock::<_, 0>::load(stock);
stock.export_to_file(terminals, output)?;
Ok(())
}
fn accept(stock: &Path, input: &Path) -> anyhow::Result<()> {
let mut stock = Stock::<_, 0>::load(stock);
stock.accept_from_file(input)?;
Ok(())
}