diff options
Diffstat (limited to 'src/bin/cli/mod.rs')
-rw-r--r-- | src/bin/cli/mod.rs | 108 |
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)), + } + } +} |