validate references in config

This commit is contained in:
Jake Howard 2017-09-10 16:23:40 +01:00
parent 5a757587b1
commit 5c85aad311
Signed by: jake
GPG key ID: 57AFB45680EDD477
6 changed files with 98 additions and 18 deletions

View file

@ -1,12 +1,12 @@
use zip::ZipArchive; use zip::ZipArchive;
use mktemp::Temp; use mktemp::Temp;
use std::path::PathBuf; use std::path::PathBuf;
use utils::get_exe_dir; use utils::{get_exe_dir, result_override};
use std::fs::File; use std::fs::File;
use std::io::{Read, Write}; use std::io::{Read, Write};
use config::consts::CSL_FILE_NAME; use config::consts::CSL_FILE_NAME;
pub fn get_csl_path() -> PathBuf { fn get_csl_path() -> PathBuf {
return get_exe_dir().join(CSL_FILE_NAME); return get_exe_dir().join(CSL_FILE_NAME);
} }
@ -15,19 +15,27 @@ fn get_temp_file() -> PathBuf {
return Temp::new_file().expect("Failed to create temporary file").to_path_buf(); return Temp::new_file().expect("Failed to create temporary file").to_path_buf();
} }
fn get_csl_data(csl_name: String) -> Result<String, String> {
let zip_file = try!(result_override(File::open(get_csl_path()), "Failed to read CSL zip".into()));
let mut archive = try!(result_override(ZipArchive::new(zip_file), "Failed to load zip file".into()));
debug_assert!(archive.len() >= 10);
let mut csl_zip_file = try!(result_override(archive.by_name(&format!("{}.csl", csl_name)), format!("Can't find CSL {}.", csl_name)));
debug_assert!(csl_zip_file.size() > 0);
let mut csl_buffer = String::new();
try!(result_override(csl_zip_file.read_to_string(&mut csl_buffer), "Failed to read CSL".into()));
return Ok(csl_buffer);
}
pub fn is_valid_csl(csl_name: String) -> bool {
return get_csl_data(csl_name).is_ok();
}
pub fn unpack_csl(csl_name: String) -> PathBuf { pub fn unpack_csl(csl_name: String) -> PathBuf {
let file = get_temp_file(); let file = get_temp_file();
let zip_file = File::open(get_csl_path()).expect("Failed to read CSL zip");
let mut archive = ZipArchive::new(zip_file).expect("Failed to load zip file");
debug_assert!(archive.len() >= 10);
let mut csl_zip_file = archive.by_name(&format!("{}.csl", csl_name)).expect(&format!(
"Failed to find CSL {}.",
csl_name
));
debug_assert!(csl_zip_file.size() > 0);
let mut csl_temp = File::create(&file).expect("Failed to open temporary file"); let mut csl_temp = File::create(&file).expect("Failed to open temporary file");
let mut csl_buffer = String::new(); let mut csl_buffer = get_csl_data(csl_name).unwrap();
csl_zip_file.read_to_string(&mut csl_buffer).expect("Failed to read CSL");
csl_temp.write_all(csl_buffer.as_bytes()).expect("Failed to write CSL to temporary file"); csl_temp.write_all(csl_buffer.as_bytes()).expect("Failed to write CSL to temporary file");
return file; return file;
} }

View file

@ -1,6 +1,6 @@
pub mod pandoc; pub mod pandoc;
pub mod process; pub mod process;
mod csl; pub mod csl;
use config::Config; use config::Config;

View file

@ -1,10 +1,12 @@
use serde_yaml::Value; use serde_yaml::Value;
use std::vec::Vec; use std::vec::Vec;
pub type ValidationResult = Result<(), String>;
use config::read; use config::read;
use config::validate_types::check_config_types; use config::validate_types::check_config_types;
use utils::resolve_path;
use build::csl::is_valid_csl;
pub type ValidationResult = Result<(), String>;
fn check_required_keys(config: Value) -> ValidationResult { fn check_required_keys(config: Value) -> ValidationResult {
@ -45,6 +47,26 @@ fn check_output_files(config: Value) -> ValidationResult {
return Ok(()); return Ok(());
} }
fn check_references(config: Value) -> ValidationResult {
if config.get("references").is_none() {
return Ok(());
}
let references = config.get("references").unwrap();
let bibliography = resolve_path(references.get("bibliography").unwrap().as_str().unwrap().into());
let valid_extensions = vec!["bib", "bibtex", "copac", "json", "yaml", "enl", "xml", "wos", "medline", "mods", "ris"];
if !bibliography.exists() {
return Err(format!("Can't find bibliography at {}.", bibliography.display()));
}
if !valid_extensions.contains(&bibliography.extension().unwrap().to_str().unwrap()) {
return Err(format!("Bibliography extension must be one of {:?}.", valid_extensions));
}
let csl = references.get("csl").unwrap().as_str().unwrap();
if !is_valid_csl(csl.into()) {
return Err(format!("{} isnt a valid CSL config.", csl));
}
return Ok(());
}
pub fn unwrap_group(config: Value, funcs: Vec<&Fn(Value) -> ValidationResult>) -> ValidationResult { pub fn unwrap_group(config: Value, funcs: Vec<&Fn(Value) -> ValidationResult>) -> ValidationResult {
for func in funcs.iter() { for func in funcs.iter() {
try!(func(config.clone())); try!(func(config.clone()));
@ -56,6 +78,6 @@ pub fn unwrap_group(config: Value, funcs: Vec<&Fn(Value) -> ValidationResult>) -
pub fn validate(config: Value) -> ValidationResult { pub fn validate(config: Value) -> ValidationResult {
return unwrap_group( return unwrap_group(
config, config,
vec![&check_required_keys, &check_config_types, &check_input_files, &check_output_files] vec![&check_required_keys, &check_config_types, &check_input_files, &check_output_files, &check_references]
); );
} }

View file

@ -1,7 +1,7 @@
use std::fmt::Debug; use std::fmt::Debug;
use std::process::exit; use std::process::exit;
use std::io::{self, Write}; use std::io::{self, Write};
use std::env::current_exe; use std::env::{current_exe, current_dir};
use std::path::PathBuf; use std::path::PathBuf;
@ -40,3 +40,8 @@ pub fn get_exe_dir() -> PathBuf {
.expect("Failed to get exe directory") .expect("Failed to get exe directory")
.to_path_buf(); .to_path_buf();
} }
pub fn resolve_path(path: String) -> PathBuf {
let base_dir = current_dir().unwrap();
return base_dir.join(path);
}

42
test-files/bib.yaml Normal file
View file

@ -0,0 +1,42 @@
---
references:
- id: item1
type: book
author:
- family: Doe
given: John
issued:
- year: '2005'
title: First book
publisher: Cambridge University Press
publisher-place: Cambridge
- id: item2
type: article-journal
author:
- family: Doe
given: John
issued:
- year: '2006'
title: Article
container-title: Journal of Generic Studies
page: '33-34'
volume: '6'
- id: item3
type: chapter
author:
- family: Doe
given: John
- family: Roe
given: Jenny
editor:
- family: Smith
given: Sam
issued:
- year: '2007'
title: Why water is wet
container-title: Third book
publisher: Oxford University Press
publisher-place: Oxford
...

View file

@ -8,3 +8,6 @@ input:
output: output:
pdf: output.pdf pdf: output.pdf
title: test title title: test title
references:
bibliography: bib.yaml
csl: apaaaaa