#![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)),
}
}
}