From bfd573105ac11d89df727d492a997a95bb760e32 Mon Sep 17 00:00:00 2001 From: trivernis Date: Wed, 2 Sep 2020 11:00:36 +0200 Subject: [PATCH] Add FromHashMap impl for book Signed-off-by: trivernis --- src/bibliography/bib_types/article.rs | 22 ++++++++++----- src/bibliography/bib_types/book.rs | 38 +++++++++++++++++++++++-- src/bibliography/bib_types/mod.rs | 39 +++++++++++++------------- src/bibliography/bibliography_entry.rs | 28 ++++++++---------- src/bibliography/keys.rs | 29 +++++++++++++++++++ src/bibliography/mod.rs | 1 + src/lib.rs | 15 ++++++++++ 7 files changed, 127 insertions(+), 45 deletions(-) create mode 100644 src/bibliography/keys.rs diff --git a/src/bibliography/bib_types/article.rs b/src/bibliography/bib_types/article.rs index 072bfe5..baf1713 100644 --- a/src/bibliography/bib_types/article.rs +++ b/src/bibliography/bib_types/article.rs @@ -1,3 +1,6 @@ +use crate::bibliography::keys::{ + K_AUTHOR, K_DATE, K_JOURNAL, K_NUMBER, K_PAGES, K_TITLE, K_URL, K_VOLUME, +}; use crate::bibliography::FromHashMap; use crate::utils::date::{parse_date, LocalDate}; use std::collections::hash_map::RandomState; @@ -13,6 +16,7 @@ pub struct Article { pub volume: Option, pub number: Option, pub pages: Option, + pub url: Option, } impl Article { @@ -26,27 +30,31 @@ impl Article { volume: None, number: None, pages: None, + url: None, } } } impl FromHashMap for Article { fn from_hash_map(map: &HashMap) -> Option> { - let author = map.get("author")?; - let title = map.get("title")?; - let journal = map.get("journal")?; - let date = parse_date(map.get("date")?)?; + 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)?)?; let mut article = Self::new(author.clone(), title.clone(), journal.clone(), date); - if let Some(volume) = map.get("volume") { + if let Some(volume) = map.get(K_VOLUME) { article.volume = Some(volume.clone()); } - if let Some(number) = map.get("number") { + if let Some(number) = map.get(K_NUMBER) { article.number = Some(number.clone()); } - if let Some(pages) = map.get("pages") { + if let Some(pages) = map.get(K_PAGES) { article.pages = Some(pages.clone()); } + if let Some(url) = map.get(K_URL) { + article.url = Some(url.clone()); + } Some(Box::new(article)) } diff --git a/src/bibliography/bib_types/book.rs b/src/bibliography/bib_types/book.rs index 732646f..6927d40 100644 --- a/src/bibliography/bib_types/book.rs +++ b/src/bibliography/bib_types/book.rs @@ -1,4 +1,10 @@ -use crate::utils::date::LocalDate; +use crate::bibliography::keys::{ + K_ADDRESS, K_AUTHOR, K_DATE, K_EDITION, K_PUBLISHER, K_SERIES, K_TITLE, K_URL, K_VOLUME, +}; +use crate::bibliography::FromHashMap; +use crate::utils::date::{parse_date, LocalDate}; +use std::collections::hash_map::RandomState; +use std::collections::HashMap; #[derive(Clone, Debug)] pub struct Book { @@ -10,7 +16,6 @@ pub struct Book { pub series: Option, pub address: Option, pub edition: Option, - pub month: Option, pub url: Option, } @@ -26,8 +31,35 @@ impl Book { series: None, address: None, edition: None, - month: None, url: None, } } } + +impl FromHashMap for Book { + fn from_hash_map(map: &HashMap) -> Option> { + 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)?)?; + let mut book = Book::new(author.clone(), title.clone(), publisher.clone(), date); + + if let Some(volume) = map.get(K_VOLUME) { + book.volume = Some(volume.clone()); + } + if let Some(series) = map.get(K_SERIES) { + book.series = Some(series.clone()); + } + if let Some(address) = map.get(K_ADDRESS) { + book.address = Some(address.clone()); + } + if let Some(edition) = map.get(K_EDITION) { + book.edition = Some(edition.clone()); + } + if let Some(url) = map.get(K_URL) { + book.url = Some(url.clone()); + } + + Some(Box::new(book)) + } +} diff --git a/src/bibliography/bib_types/mod.rs b/src/bibliography/bib_types/mod.rs index e18ceac..ee45835 100644 --- a/src/bibliography/bib_types/mod.rs +++ b/src/bibliography/bib_types/mod.rs @@ -10,6 +10,10 @@ use crate::bibliography::bib_types::tech_report::TechReport; use crate::bibliography::bib_types::thesis::Thesis; use crate::bibliography::bib_types::unpublished::Unpublished; use crate::bibliography::bib_types::website::Website; +use crate::bibliography::keys::{ + K_TYPE, T_ARTICLE, T_BOOK, T_BOOKLET, T_IN_BOOK, T_IN_COLLECTION, T_MANUAL, T_MISC, + T_REPOSITORY, T_TECH_REPORT, T_THESIS, T_UNPUBLISHED, T_WEBSITE, +}; use crate::bibliography::FromHashMap; use std::collections::HashMap; @@ -47,31 +51,28 @@ impl BibliographyType { /// Returns the name of the enums value as a string pub fn name(&self) -> String { match self { - Self::Article(_) => "article".to_string(), - Self::Book(_) => "book".to_string(), - Self::Booklet(_) => "booklet".to_string(), - Self::InBook(_) => "in_book".to_string(), - Self::InCollection(_) => "in_collection".to_string(), - Self::Manual(_) => "manual".to_string(), - Self::Thesis(_) => "thesis".to_string(), - Self::TechReport(_) => "tech_report".to_string(), - Self::Unpublished(_) => "unpublished".to_string(), - Self::Misc(_) => "misc".to_string(), - Self::Website(_) => "website".to_string(), - Self::Repository(_) => "repository".to_string(), + Self::Article(_) => T_ARTICLE.to_string(), + Self::Book(_) => T_BOOK.to_string(), + Self::Booklet(_) => T_BOOKLET.to_string(), + Self::InBook(_) => T_IN_BOOK.to_string(), + Self::InCollection(_) => T_IN_COLLECTION.to_string(), + Self::Manual(_) => T_MANUAL.to_string(), + Self::Thesis(_) => T_THESIS.to_string(), + Self::TechReport(_) => T_TECH_REPORT.to_string(), + Self::Unpublished(_) => T_UNPUBLISHED.to_string(), + Self::Misc(_) => T_MISC.to_string(), + Self::Website(_) => T_WEBSITE.to_string(), + Self::Repository(_) => T_REPOSITORY.to_string(), } } } impl FromHashMap for BibliographyType { fn from_hash_map(map: &HashMap) -> Option> { - if map.contains_key("type") { - match map.get("type").unwrap().as_str() { - "article" => Some(Box::new(Self::Article(*Article::from_hash_map(map)?))), - _ => None, - } - } else { - None + 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)?))), + _ => None, } } } diff --git a/src/bibliography/bibliography_entry.rs b/src/bibliography/bibliography_entry.rs index f71e029..e75e7ee 100644 --- a/src/bibliography/bibliography_entry.rs +++ b/src/bibliography/bibliography_entry.rs @@ -1,5 +1,6 @@ use crate::bibliography::bib_types::misc::Misc; use crate::bibliography::bib_types::BibliographyType; +use crate::bibliography::keys::{K_KEY, K_NOTE}; use crate::bibliography::FromHashMap; use std::collections::hash_map::RandomState; use std::collections::HashMap; @@ -35,22 +36,17 @@ impl BibliographyEntry { impl FromHashMap for BibliographyEntry { fn from_hash_map(map: &HashMap) -> Option> { - if let Some(key) = map.get("key") { - if let Some(bib_type) = BibliographyType::from_hash_map(map) { - let mut entry = Self::new(key.clone()); - - if let Some(note) = map.get("note") { - entry.note = Some(note.clone()) - } - entry.bib_type = *bib_type; - entry.raw_fields = map.clone(); - - Some(Box::new(entry)) - } else { - None - } - } else { - None + let key = map.get(K_KEY)?; + let bib_type = BibliographyType::from_hash_map(map)?; + + let mut entry = Self::new(key.clone()); + + if let Some(note) = map.get(K_NOTE) { + entry.note = Some(note.clone()) } + entry.bib_type = *bib_type; + entry.raw_fields = map.clone(); + + Some(Box::new(entry)) } } diff --git a/src/bibliography/keys.rs b/src/bibliography/keys.rs new file mode 100644 index 0000000..a8b50f6 --- /dev/null +++ b/src/bibliography/keys.rs @@ -0,0 +1,29 @@ +pub const K_KEY: &str = "key"; +pub const K_TYPE: &str = "type"; +pub const K_AUTHOR: &str = "author"; +pub const K_TITLE: &str = "title"; +pub const K_DATE: &str = "date"; +pub const K_PUBLISHER: &str = "publisher"; +pub const K_VOLUME: &str = "volume"; +pub const K_URL: &str = "url"; +pub const K_SERIES: &str = "series"; +pub const K_ADDRESS: &str = "address"; +pub const K_JOURNAL: &str = "journal"; +pub const K_EDITION: &str = "edition"; +pub const K_LICENSE: &str = "license"; +pub const K_NUMBER: &str = "number"; +pub const K_PAGES: &str = "pages"; +pub const K_NOTE: &str = "note"; + +pub const T_ARTICLE: &str = "article"; +pub const T_BOOK: &str = "book"; +pub const T_BOOKLET: &str = "booklet"; +pub const T_IN_BOOK: &str = "in_book"; +pub const T_IN_COLLECTION: &str = "in_collection"; +pub const T_MANUAL: &str = "manual"; +pub const T_MISC: &str = "misc"; +pub const T_REPOSITORY: &str = "repository"; +pub const T_TECH_REPORT: &str = "tech_report"; +pub const T_THESIS: &str = "thesis"; +pub const T_UNPUBLISHED: &str = "unpublished"; +pub const T_WEBSITE: &str = "website"; diff --git a/src/bibliography/mod.rs b/src/bibliography/mod.rs index 533c22a..f343527 100644 --- a/src/bibliography/mod.rs +++ b/src/bibliography/mod.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; pub mod bib_types; pub mod bibliography_dict; pub mod bibliography_entry; +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 diff --git a/src/lib.rs b/src/lib.rs index dcf9dff..fc2fdb8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,4 +45,19 @@ mod tests { let entry = BibliographyEntry::from_hash_map(&map).unwrap(); assert_eq!(entry.bib_type.name(), "article".to_string()) } + + #[test] + fn it_creates_books_from_hashmaps() { + let mut map: HashMap = HashMap::new(); + map.insert("key".to_string(), "test_entry".to_string()); + map.insert("type".to_string(), "book".to_string()); + map.insert("author".to_string(), "test".to_string()); + map.insert("title".to_string(), "test_title".to_string()); + map.insert("publisher".to_string(), "test_publisher".to_string()); + map.insert("date".to_string(), "01.09.2020".to_string()); + map.insert("note".to_string(), "This is a test".to_string()); + + let entry = BibliographyEntry::from_hash_map(&map).unwrap(); + assert_eq!(entry.bib_type.name(), "book".to_string()) + } }