summaryrefslogtreecommitdiff
path: root/src/bin/sp-meta.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/sp-meta.rs')
-rw-r--r--src/bin/sp-meta.rs114
1 files changed, 96 insertions, 18 deletions
diff --git a/src/bin/sp-meta.rs b/src/bin/sp-meta.rs
index cfa3b3d..49f6173 100644
--- a/src/bin/sp-meta.rs
+++ b/src/bin/sp-meta.rs
@@ -1,43 +1,121 @@
use anyhow::Result;
+use std::convert::TryFrom;
use std::path::{Path, PathBuf};
+use std::str::FromStr;
+
+use serde::Serialize;
use structopt::StructOpt;
use subplot::Document;
+#[derive(Debug)]
+enum OutputFormat {
+ Plain,
+ Json,
+}
+
+impl FromStr for OutputFormat {
+ type Err = String;
+
+ fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
+ match s.to_ascii_lowercase().as_ref() {
+ "plain" => Ok(OutputFormat::Plain),
+ "json" => Ok(OutputFormat::Json),
+ _ => Err(format!("Unknown output format: `{}`", s)),
+ }
+ }
+}
+
#[derive(Debug, StructOpt)]
#[structopt(name = "sp-meta", about = "Show Subplot document metadata.")]
struct Opt {
- // Input filename.
+ /// Form that you want the output to take
+ #[structopt(short = "o", default_value = "plain", possible_values=&["plain", "json"])]
+ output_format: OutputFormat,
+ /// Input subplot document filename
#[structopt(parse(from_os_str))]
filename: PathBuf,
}
-fn main() -> Result<()> {
- let opt = Opt::from_args();
- let basedir = subplot::get_basedir_from(&opt.filename)?;
- let mut doc = Document::from_file(&basedir, &opt.filename)?;
+#[derive(Serialize)]
+struct Metadata {
+ sources: Vec<String>,
+ title: String,
+ binding_files: Vec<String>,
+ function_files: Vec<String>,
+ bibliographies: Vec<String>,
+ scenarios: Vec<String>,
+}
- for filename in doc.sources() {
- println!("source: {}", filename.display());
+impl TryFrom<&mut Document> for Metadata {
+ type Error = subplot::SubplotError;
+ fn try_from(doc: &mut Document) -> std::result::Result<Self, Self::Error> {
+ let sources: Vec<_> = doc
+ .sources()
+ .into_iter()
+ .map(|p| filename(Some(&p)))
+ .collect();
+ let title = doc.meta().title().to_owned();
+ let binding_files = doc
+ .meta()
+ .bindings_filenames()
+ .into_iter()
+ .map(|p| filename(Some(&p)))
+ .collect();
+ let function_files = doc
+ .meta()
+ .functions_filenames()
+ .into_iter()
+ .map(|p| filename(Some(&p)))
+ .collect();
+ let bibliographies = doc
+ .meta()
+ .bibliographies()
+ .into_iter()
+ .map(|p| filename(Some(&p)))
+ .collect();
+ let scenarios = doc
+ .scenarios()?
+ .into_iter()
+ .map(|s| s.title().to_owned())
+ .collect();
+ Ok(Self {
+ sources,
+ title,
+ binding_files,
+ function_files,
+ bibliographies,
+ scenarios,
+ })
}
+}
- println!("title: {}", doc.meta().title());
-
- for filename in doc.meta().bindings_filenames() {
- println!("bindings: {}", filename.display());
+impl Metadata {
+ fn write_list(v: &[String], prefix: &str) {
+ v.iter().for_each(|entry| println!("{}: {}", prefix, entry))
}
- for filename in doc.meta().functions_filenames() {
- println!("functions: {}", filename.display());
+ fn write_out(&self) {
+ Self::write_list(&self.sources, "source");
+ println!("title: {}", self.title);
+ Self::write_list(&self.binding_files, "bindings");
+ Self::write_list(&self.function_files, "functions");
+ Self::write_list(&self.bibliographies, "bibliography");
+ Self::write_list(&self.scenarios, "scenario");
}
+}
- for bib in doc.meta().bibliographies().iter() {
- println!("bibliography: {}", filename(Some(bib)));
- }
+fn main() -> Result<()> {
+ let opt = Opt::from_args();
+ let basedir = subplot::get_basedir_from(&opt.filename)?;
+ let mut doc = Document::from_file(&basedir, &opt.filename)?;
+ let meta = Metadata::try_from(&mut doc)?;
- for scen in doc.scenarios()? {
- println!("scenario {}", scen.title());
+ match opt.output_format {
+ OutputFormat::Plain => meta.write_out(),
+ OutputFormat::Json => println!("{}", serde_json::to_string_pretty(&meta)?),
}
+
Ok(())
}