From c01c05e6cb9199832b9067b66f757044b7493170 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 13 Feb 2021 12:10:27 +0000 Subject: bin: Initial subplot binary, only implements extract Signed-off-by: Daniel Silverstone --- src/bin/subplot.rs | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/bin/subplot.rs diff --git a/src/bin/subplot.rs b/src/bin/subplot.rs new file mode 100644 index 0000000..38e129e --- /dev/null +++ b/src/bin/subplot.rs @@ -0,0 +1,111 @@ +//! Subplot top level binary +//! + +use anyhow::Result; + +use structopt::StructOpt; +use subplot::{resource, DataFile, Style}; + +use std::fs::write; +use std::path::PathBuf; +use std::process; + +mod cli; + +#[derive(Debug, StructOpt)] +struct Toplevel { + #[structopt(flatten)] + resources: resource::ResourceOpts, + + #[structopt(flatten)] + command: Cmd, +} + +impl Toplevel { + fn run(&self) -> Result<()> { + self.command.run() + } +} + +#[derive(Debug, StructOpt)] +enum Cmd { + Extract(Extract), +} + +impl Cmd { + fn run(&self) -> Result<()> { + match self { + Cmd::Extract(e) => e.run(), + } + } +} + +#[derive(Debug, StructOpt)] +/// Extract embedded files from a subplot document +/// +/// If no embedded filenames are provided, this will +/// extract all embedded files. if the output directory +/// is not specified then this will extract to the current directory. +struct Extract { + /// Directory to write extracted files to + #[structopt( + name = "DIR", + long = "directory", + short = "d", + parse(from_os_str), + default_value = "." + )] + directory: PathBuf, + + /// Don't actually write the files out + #[structopt(long)] + dry_run: bool, + + /// Input subplot document filename + #[structopt(parse(from_os_str))] + filename: PathBuf, + + /// Names of embedded files to be extracted. + embedded: Vec, +} + +impl Extract { + fn run(&self) -> Result<()> { + let doc = cli::load_document(&self.filename, Style::default())?; + + let files: Vec<&DataFile> = if self.embedded.is_empty() { + doc.files() + .iter() + .map(Result::Ok) + .collect::>>() + } else { + self.embedded + .iter() + .map(|filename| cli::extract_file(&doc, filename)) + .collect::>>() + }?; + + for f in files { + let outfile = self.directory.join(f.filename()); + if self.dry_run { + println!("Would write out {}", outfile.display()); + } else { + write(outfile, f.contents())? + } + } + + Ok(()) + } +} + +fn main() { + let args = Toplevel::from_args(); + args.resources.handle(); + match args.run() { + Ok(_) => {} + Err(e) => { + eprintln!("Failure: {:?}", e); + process::exit(1); + } + } +} -- cgit v1.2.1