Change FromHashMap insertion return value to Result

Signed-off-by: trivernis <trivernis@protonmail.com>
main
trivernis 4 years ago
parent d27f33fb21
commit 741bdc6e12
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,7 +1,7 @@
[package]
name = "bibliographix"
description = "A bibliography management crate."
version = "0.4.0"
version = "0.5.0"
authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018"
license = "Apache-2.0"

@ -99,7 +99,7 @@ impl BibManager {
entry_map.insert(K_KEY.to_string(), k.clone());
Some(*BibliographyEntry::from_hash_map(&entry_map)?)
Some(*BibliographyEntry::from_hash_map(&entry_map).ok()?)
})
.collect::<Vec<BibliographyEntry>>();

@ -36,11 +36,11 @@ impl Article {
}
impl FromHashMap for Article {
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Option<Box<Self>> {
let author = map.get(K_AUTHOR)?;
let title = map.get(K_TITLE)?;
let journal = map.get(K_JOURNAL)?;
let date = parse_date(map.get(K_DATE)?)?;
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Result<Box<Self>, String> {
let author = map.get(K_AUTHOR).ok_or(missing_field!(K_AUTHOR))?;
let title = map.get(K_TITLE).ok_or(missing_field!(K_TITLE))?;
let journal = map.get(K_JOURNAL).ok_or(missing_field!(K_JOURNAL))?;
let date = parse_date(map.get(K_DATE).ok_or(missing_field!(K_DATE))?)?;
let mut article = Self::new(author.clone(), title.clone(), journal.clone(), date);
article.volume = map.get(K_VOLUME).cloned();
@ -49,6 +49,6 @@ impl FromHashMap for Article {
article.pages = map.get(K_PAGES).cloned();
article.url = map.get(K_URL).cloned();
Some(Box::new(article))
Ok(Box::new(article))
}
}

@ -37,11 +37,11 @@ impl Book {
}
impl FromHashMap for Book {
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Option<Box<Self>> {
let author = map.get(K_AUTHOR)?;
let title = map.get(K_TITLE)?;
let publisher = map.get(K_PUBLISHER)?;
let date = parse_date(map.get(K_DATE)?)?;
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Result<Box<Self>, String> {
let author = map.get(K_AUTHOR).ok_or(missing_field!(K_AUTHOR))?;
let title = map.get(K_TITLE).ok_or(missing_field!(K_TITLE))?;
let publisher = map.get(K_PUBLISHER).ok_or(missing_field!(K_PUBLISHER))?;
let date = parse_date(map.get(K_DATE).ok_or(missing_field!(K_DATE))?)?;
let mut book = Book::new(author.clone(), title.clone(), publisher.clone(), date);
book.volume = map.get(K_VOLUME).cloned();
@ -50,6 +50,6 @@ impl FromHashMap for Book {
book.edition = map.get(K_EDITION).cloned();
book.url = map.get(K_URL).cloned();
Some(Box::new(book))
Ok(Box::new(book))
}
}

@ -28,15 +28,19 @@ impl Booklet {
}
impl FromHashMap for Booklet {
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Option<Box<Self>> {
let title = map.get(K_TITLE)?;
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Result<Box<Self>, String> {
let title = map.get(K_TITLE).ok_or(missing_field!(K_TITLE))?;
let mut booklet = Booklet::new(title.clone());
booklet.author = map.get(K_AUTHOR).cloned();
booklet.how_published = map.get(K_HOW_PUBLISHED).cloned();
booklet.address = map.get(K_ADDRESS).cloned();
booklet.date = map.get(K_DATE).and_then(|d| parse_date(d));
booklet.date = map
.get(K_DATE)
.ok_or(missing_field!(K_DATE))
.and_then(|d| parse_date(d))
.ok();
Some(Box::new(booklet))
Ok(Box::new(booklet))
}
}

@ -1,5 +1,5 @@
use crate::bibliography::keys::{
K_ADDRESS, K_AUTHOR, K_DATE, K_EDITION, K_PUBLISHER, K_SERIES, K_TITLE, K_VOLUME,
K_ADDRESS, K_AUTHOR, K_DATE, K_EDITION, K_POSITION, K_PUBLISHER, K_SERIES, K_TITLE, K_VOLUME,
};
use crate::bibliography::FromHashMap;
use crate::utils::date::{parse_date, LocalDate};
@ -44,12 +44,12 @@ impl InBook {
}
impl FromHashMap for InBook {
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Option<Box<Self>> {
let author = map.get(K_AUTHOR)?;
let title = map.get(K_TITLE)?;
let position = map.get(K_TITLE)?;
let publisher = map.get(K_PUBLISHER)?;
let date = parse_date(map.get(K_DATE)?)?;
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Result<Box<Self>, String> {
let author = map.get(K_AUTHOR).ok_or(missing_field!(K_AUTHOR))?;
let title = map.get(K_TITLE).ok_or(missing_field!(K_TITLE))?;
let position = map.get(K_POSITION).ok_or(missing_field!(K_POSITION))?;
let publisher = map.get(K_PUBLISHER).ok_or(missing_field!(K_PUBLISHER))?;
let date = parse_date(map.get(K_DATE).ok_or(missing_field!(K_DATE))?)?;
let mut in_book = InBook::new(
author.clone(),
title.clone(),
@ -63,6 +63,6 @@ impl FromHashMap for InBook {
in_book.address = map.get(K_ADDRESS).cloned();
in_book.edition = map.get(K_EDITION).cloned();
Some(Box::new(in_book))
Ok(Box::new(in_book))
}
}

@ -41,28 +41,20 @@ impl InCollection {
}
impl FromHashMap for InCollection {
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Option<Box<Self>> {
let author = map.get(K_AUTHOR)?;
let title = map.get(K_TITLE)?;
let publisher = map.get(K_PUBLISHER)?;
let date = parse_date(map.get(K_DATE)?)?;
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Result<Box<Self>, String> {
let author = map.get(K_AUTHOR).ok_or(missing_field!(K_AUTHOR))?;
let title = map.get(K_TITLE).ok_or(missing_field!(K_TITLE))?;
let publisher = map.get(K_PUBLISHER).ok_or(missing_field!(K_PUBLISHER))?;
let date = parse_date(map.get(K_DATE).ok_or(missing_field!(K_DATE))?)?;
let mut in_col = InCollection::new(author.clone(), title.clone(), publisher.clone(), date);
in_col.editor = map.get(K_EDITOR).cloned();
in_col.volume = map.get(K_VOLUME).cloned();
if let Some(series) = map.get(K_SERIES) {
Some(series.clone());
}
if let Some(position) = map.get(K_POSITION) {
in_col.position = Some(position.clone());
}
if let Some(address) = map.get(K_ADDRESS) {
in_col.address = Some(address.clone());
}
if let Some(edition) = map.get(K_EDITION) {
in_col.edition = Some(edition.clone());
}
in_col.series = map.get(K_SERIES).cloned();
in_col.position = map.get(K_POSITION).cloned();
in_col.address = map.get(K_ADDRESS).cloned();
in_col.edition = map.get(K_EDITION).cloned();
Some(Box::new(in_col))
Ok(Box::new(in_col))
}
}

@ -30,16 +30,20 @@ impl Manual {
}
impl FromHashMap for Manual {
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Option<Box<Self>> {
let title = map.get(K_TITLE)?;
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Result<Box<Self>, String> {
let title = map.get(K_TITLE).ok_or(missing_field!(K_TITLE))?;
let mut manual = Manual::new(title.clone());
manual.author = map.get(K_AUTHOR).cloned();
manual.organization = map.get(K_ORGANIZATION).cloned();
manual.address = map.get(K_ADDRESS).cloned();
manual.edition = map.get(K_EDITION).cloned();
manual.date = map.get(K_DATE).and_then(|d| parse_date(d));
manual.date = map
.get(K_DATE)
.ok_or(missing_field!(K_DATE))
.and_then(|d| parse_date(d))
.ok();
Some(Box::new(manual))
Ok(Box::new(manual))
}
}

@ -28,15 +28,19 @@ impl Misc {
}
impl FromHashMap for Misc {
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Option<Box<Self>> {
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Result<Box<Self>, String> {
let mut misc = Misc::new();
misc.author = map.get(K_AUTHOR).cloned();
misc.title = map.get(K_TITLE).cloned();
misc.url = map.get(K_URL).cloned();
misc.how_published = map.get(K_HOW_PUBLISHED).cloned();
misc.date = map.get(K_DATE).and_then(|d| parse_date(d));
misc.date = map
.get(K_DATE)
.ok_or(missing_field!(K_DATE))
.and_then(|d| parse_date(d))
.ok();
Some(Box::new(misc))
Ok(Box::new(misc))
}
}

@ -68,25 +68,25 @@ impl BibliographyType {
}
impl FromHashMap for BibliographyType {
fn from_hash_map(map: &HashMap<String, String>) -> Option<Box<Self>> {
match map.get(K_TYPE)?.as_str() {
T_ARTICLE => Some(Box::new(Self::Article(*Article::from_hash_map(map)?))),
T_BOOK => Some(Box::new(Self::Book(*Book::from_hash_map(map)?))),
T_BOOKLET => Some(Box::new(Self::Booklet(*Booklet::from_hash_map(map)?))),
T_IN_BOOK => Some(Box::new(Self::InBook(*InBook::from_hash_map(map)?))),
T_IN_COLLECTION => Some(Box::new(Self::InCollection(*InCollection::from_hash_map(
fn from_hash_map(map: &HashMap<String, String>) -> Result<Box<Self>, String> {
match map.get(K_TYPE).ok_or(missing_field!(K_TYPE))?.as_str() {
T_ARTICLE => Ok(Box::new(Self::Article(*Article::from_hash_map(map)?))),
T_BOOK => Ok(Box::new(Self::Book(*Book::from_hash_map(map)?))),
T_BOOKLET => Ok(Box::new(Self::Booklet(*Booklet::from_hash_map(map)?))),
T_IN_BOOK => Ok(Box::new(Self::InBook(*InBook::from_hash_map(map)?))),
T_IN_COLLECTION => Ok(Box::new(Self::InCollection(*InCollection::from_hash_map(
map,
)?))),
T_MANUAL => Some(Box::new(Self::Manual(*Manual::from_hash_map(map)?))),
T_MISC => Some(Box::new(Self::Misc(*Misc::from_hash_map(map)?))),
T_REPOSITORY => Some(Box::new(Self::Repository(*Repository::from_hash_map(map)?))),
T_TECH_REPORT => Some(Box::new(Self::TechReport(*TechReport::from_hash_map(map)?))),
T_THESIS => Some(Box::new(Self::Thesis(*Thesis::from_hash_map(map)?))),
T_UNPUBLISHED => Some(Box::new(Self::Unpublished(*Unpublished::from_hash_map(
T_MANUAL => Ok(Box::new(Self::Manual(*Manual::from_hash_map(map)?))),
T_MISC => Ok(Box::new(Self::Misc(*Misc::from_hash_map(map)?))),
T_REPOSITORY => Ok(Box::new(Self::Repository(*Repository::from_hash_map(map)?))),
T_TECH_REPORT => Ok(Box::new(Self::TechReport(*TechReport::from_hash_map(map)?))),
T_THESIS => Ok(Box::new(Self::Thesis(*Thesis::from_hash_map(map)?))),
T_UNPUBLISHED => Ok(Box::new(Self::Unpublished(*Unpublished::from_hash_map(
map,
)?))),
T_WEBSITE => Some(Box::new(Self::Website(*Website::from_hash_map(map)?))),
_ => None,
T_WEBSITE => Ok(Box::new(Self::Website(*Website::from_hash_map(map)?))),
_ => Err(format!("Unknown type")),
}
}
}

@ -31,16 +31,20 @@ impl Repository {
}
impl FromHashMap for Repository {
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Option<Box<Self>> {
let author = map.get(K_AUTHOR)?;
let title = map.get(K_TITLE)?;
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Result<Box<Self>, String> {
let author = map.get(K_AUTHOR).ok_or(missing_field!(K_AUTHOR))?;
let title = map.get(K_TITLE).ok_or(missing_field!(K_TITLE))?;
let mut repo = Repository::new(author.clone(), title.clone());
repo.url = map.get(K_URL).cloned();
repo.license = map.get(K_LICENSE).cloned();
repo.cms = map.get(K_CMS).cloned();
repo.accessed_at = map.get(K_ACCESSED_AT).and_then(|d| parse_date(d));
repo.accessed_at = map
.get(K_ACCESSED_AT)
.ok_or(missing_field!(K_ACCESSED_AT))
.and_then(|d| parse_date(d))
.ok();
Some(Box::new(repo))
Ok(Box::new(repo))
}
}

@ -30,17 +30,22 @@ impl TechReport {
}
impl FromHashMap for TechReport {
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Option<Box<Self>> {
let author = map.get(K_AUTHOR)?;
let title = map.get(K_TITLE)?;
let institution = map.get(K_INSTITUTION)?;
let date = map.get(K_DATE).and_then(|d| parse_date(d))?;
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Result<Box<Self>, String> {
let author = map.get(K_AUTHOR).ok_or(missing_field!(K_AUTHOR))?;
let title = map.get(K_TITLE).ok_or(missing_field!(K_TITLE))?;
let institution = map
.get(K_INSTITUTION)
.ok_or(missing_field!(K_INSTITUTION))?;
let date = map
.get(K_DATE)
.ok_or(missing_field!(K_DATE))
.and_then(|d| parse_date(d))?;
let mut tech_report =
TechReport::new(author.clone(), title.clone(), institution.clone(), date);
tech_report.number = map.get(K_NUMBER).cloned();
tech_report.address = map.get(K_ADDRESS).cloned();
Some(Box::new(tech_report))
Ok(Box::new(tech_report))
}
}

@ -28,15 +28,18 @@ impl Thesis {
}
impl FromHashMap for Thesis {
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Option<Box<Self>> {
let author = map.get(K_AUTHOR)?;
let title = map.get(K_TITLE)?;
let school = map.get(K_SCHOOL)?;
let date = map.get(K_DATE).and_then(|d| parse_date(d))?;
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Result<Box<Self>, String> {
let author = map.get(K_AUTHOR).ok_or(missing_field!(K_AUTHOR))?;
let title = map.get(K_TITLE).ok_or(missing_field!(K_TITLE))?;
let school = map.get(K_SCHOOL).ok_or(missing_field!(K_SCHOOL))?;
let date = map
.get(K_DATE)
.ok_or(missing_field!(K_DATE))
.and_then(|d| parse_date(d))?;
let mut thesis = Thesis::new(author.clone(), title.clone(), school.clone(), date.clone());
thesis.address = map.get(K_ADDRESS).cloned();
Some(Box::new(thesis))
Ok(Box::new(thesis))
}
}

@ -24,13 +24,13 @@ impl Unpublished {
}
impl FromHashMap for Unpublished {
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Option<Box<Self>> {
let author = map.get(K_AUTHOR)?;
let title = map.get(K_TITLE)?;
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Result<Box<Self>, String> {
let author = map.get(K_AUTHOR).ok_or(missing_field!(K_AUTHOR))?;
let title = map.get(K_TITLE).ok_or(missing_field!(K_TITLE))?;
let mut unpub = Unpublished::new(author.clone(), title.clone());
unpub.date = map.get(K_DATE).and_then(|d| parse_date(d));
unpub.date = map.get(K_DATE).and_then(|d| parse_date(d).ok());
Some(Box::new(unpub))
Ok(Box::new(unpub))
}
}

@ -28,15 +28,15 @@ impl Website {
}
impl FromHashMap for Website {
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Option<Box<Self>> {
let url = map.get(K_URL)?;
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Result<Box<Self>, String> {
let url = map.get(K_URL).ok_or(missing_field!(K_URL))?;
let mut website = Website::new(url.clone());
website.title = map.get(K_TITLE).cloned();
website.author = map.get(K_AUTHOR).cloned();
website.accessed_at = map.get(K_ACCESSED_AT).and_then(|d| parse_date(d));
website.date = map.get(K_DATE).and_then(|d| parse_date(d));
website.accessed_at = map.get(K_ACCESSED_AT).and_then(|d| parse_date(d).ok());
website.date = map.get(K_DATE).and_then(|d| parse_date(d).ok());
Some(Box::new(website))
Ok(Box::new(website))
}
}

@ -25,13 +25,13 @@ impl BibliographyDictionary {
}
/// Inserts a bibliography entry represented as a HashMap
pub fn insert_map(&mut self, map: &HashMap<String, String>) -> Option<()> {
let key = map.get(K_KEY)?;
pub fn insert_map(&mut self, map: &HashMap<String, String>) -> Result<(), String> {
let key = map.get(K_KEY).ok_or(missing_field!(K_KEY))?;
let entry = *BibliographyEntry::from_hash_map(map)?;
self.entries
.insert(key.clone(), Arc::new(Mutex::new(entry)));
Some(())
Ok(())
}
/// Returns the reference to the bibliography entry with the given key

@ -35,8 +35,8 @@ impl BibliographyEntry {
}
impl FromHashMap for BibliographyEntry {
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Option<Box<Self>> {
let key = map.get(K_KEY)?;
fn from_hash_map(map: &HashMap<String, String, RandomState>) -> Result<Box<Self>, String> {
let key = map.get(K_KEY).ok_or(missing_field!(K_KEY))?;
let bib_type = BibliographyType::from_hash_map(map)?;
let mut entry = Self::new(key.clone());
@ -45,6 +45,6 @@ impl FromHashMap for BibliographyEntry {
entry.bib_type = *bib_type;
entry.raw_fields = map.clone();
Some(Box::new(entry))
Ok(Box::new(entry))
}
}

@ -1,5 +1,11 @@
use std::collections::HashMap;
macro_rules! missing_field {
($e:expr) => {
format!("Missing field '{}'", $e)
};
}
pub mod bib_types;
pub mod bibliography_dict;
pub mod bibliography_entry;
@ -8,5 +14,5 @@ pub mod keys;
/// A trait that provides the from_has_map function that can be used
/// to create a bibliography source type from a hashmap
pub trait FromHashMap {
fn from_hash_map(map: &HashMap<String, String>) -> Option<Box<Self>>;
fn from_hash_map(map: &HashMap<String, String>) -> Result<Box<Self>, String>;
}

@ -50,7 +50,12 @@ mod tests {
map.insert("title".to_string(), "test_title".to_string());
map.insert("journal".to_string(), "test_journal".to_string());
map.insert("date".to_string(), "01.09.2020".to_string());
manager.entry_dictionary().lock().unwrap().insert_map(&map);
manager
.entry_dictionary()
.lock()
.unwrap()
.insert_map(&map)
.unwrap();
manager.assign_entries_to_references();
assert!(anchor1.lock().unwrap().entry.is_some());

@ -3,11 +3,10 @@ use chrono_english::Dialect;
pub type LocalDate = Date<Local>;
pub fn parse_date(date_str: &str) -> Option<LocalDate> {
pub fn parse_date(date_str: &str) -> Result<LocalDate, String> {
let date_str = date_str.replace('.', "/");
if let Ok(datetime) = chrono_english::parse_date_string(&date_str, Local::now(), Dialect::Us) {
Some(datetime.date())
} else {
None
}
chrono_english::parse_date_string(&date_str, Local::now(), Dialect::Us)
.map(|d| d.date())
.map_err(|e| e.to_string())
}

Loading…
Cancel
Save