summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2021-02-13 12:10:27 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2021-04-09 16:42:49 +0100
commitc01c05e6cb9199832b9067b66f757044b7493170 (patch)
treec8ea2cc45b5f1a070c48a1d678af1e809b527b79
parent279c4335737667cbcf640bda799a783d14ad4b2b (diff)
downloadsubplot-c01c05e6cb9199832b9067b66f757044b7493170.tar.gz
bin: Initial subplot binary, only implements extract
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
-rw-r--r--src/bin/subplot.rs111
1 files changed, 111 insertions, 0 deletions
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<String>,
+}
+
+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::<Result<Vec<_>>>()
+ } else {
+ self.embedded
+ .iter()
+ .map(|filename| cli::extract_file(&doc, filename))
+ .collect::<Result<Vec<_>>>()
+ }?;
+
+ 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);
+ }
+ }
+}