validate references in config
This commit is contained in:
parent
5a757587b1
commit
5c85aad311
6 changed files with 98 additions and 18 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
42
test-files/bib.yaml
Normal 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
|
||||||
|
...
|
|
@ -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
|
||||||
|
|
Reference in a new issue