summaryrefslogtreecommitdiff
path: root/src/bin/cli/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/cli/mod.rs')
-rw-r--r--src/bin/cli/mod.rs108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/bin/cli/mod.rs b/src/bin/cli/mod.rs
index 855a066..f3225db 100644
--- a/src/bin/cli/mod.rs
+++ b/src/bin/cli/mod.rs
@@ -3,9 +3,12 @@
#![allow(unused)]
use anyhow::Result;
+use serde::Serialize;
use subplot::{DataFile, Document, Style, SubplotError};
+use std::convert::TryFrom;
use std::path::Path;
+use std::str::FromStr;
pub fn load_document<P: AsRef<Path>>(filename: P, style: Style) -> Result<Document> {
let filename = filename.as_ref();
@@ -23,3 +26,108 @@ pub fn extract_file<'a>(doc: &'a Document, filename: &str) -> Result<&'a DataFil
}
Err(SubplotError::EmbeddedFileNotFound(filename.to_owned()).into())
}
+
+#[derive(Serialize)]
+pub struct Metadata {
+ sources: Vec<String>,
+ title: String,
+ binding_files: Vec<String>,
+ function_files: Vec<String>,
+ bibliographies: Vec<String>,
+ scenarios: Vec<String>,
+ files: Vec<String>,
+}
+
+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();
+ let files = doc
+ .files()
+ .iter()
+ .map(|f| f.filename().to_owned())
+ .collect();
+ Ok(Self {
+ sources,
+ title,
+ binding_files,
+ function_files,
+ bibliographies,
+ scenarios,
+ files,
+ })
+ }
+}
+
+impl Metadata {
+ fn write_list(v: &[String], prefix: &str) {
+ v.iter().for_each(|entry| println!("{}: {}", prefix, entry))
+ }
+
+ pub 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.files, "file");
+ Self::write_list(&self.scenarios, "scenario");
+ }
+}
+
+fn filename(name: Option<&Path>) -> String {
+ let path = match name {
+ None => return "".to_string(),
+ Some(x) => x,
+ };
+ match path.to_str() {
+ None => "non-UTF8 filename".to_string(),
+ Some(x) => x.to_string(),
+ }
+}
+
+#[derive(Debug)]
+pub 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)),
+ }
+ }
+}