diff options
Diffstat (limited to 'src/bin/cli/mod.rs')
-rw-r--r-- | src/bin/cli/mod.rs | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/src/bin/cli/mod.rs b/src/bin/cli/mod.rs new file mode 100644 index 0000000..f3225db --- /dev/null +++ b/src/bin/cli/mod.rs @@ -0,0 +1,133 @@ +//! CLI Functionality abstractions + +#![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(); + let base_path = subplot::get_basedir_from(filename)?; + let doc = Document::from_file(&base_path, filename, style)?; + + Ok(doc) +} + +pub fn extract_file<'a>(doc: &'a Document, filename: &str) -> Result<&'a DataFile> { + for file in doc.files() { + if file.filename() == filename { + return Ok(file); + } + } + 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)), + } + } +} |