diff --git a/Cargo.toml b/Cargo.toml index 035a04f..cd61ea3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,5 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -chrono = "0.4.15" \ No newline at end of file +chrono = "0.4.15" +chrono-english = "0.1.4" \ No newline at end of file diff --git a/src/bibliography/bib_types/article.rs b/src/bibliography/bib_types/article.rs index 346cee9..072bfe5 100644 --- a/src/bibliography/bib_types/article.rs +++ b/src/bibliography/bib_types/article.rs @@ -1,4 +1,7 @@ -use crate::bibliography::bib_types::LocalDate; +use crate::bibliography::FromHashMap; +use crate::utils::date::{parse_date, LocalDate}; +use std::collections::hash_map::RandomState; +use std::collections::HashMap; /// An article source #[derive(Clone, Debug)] @@ -26,3 +29,25 @@ impl Article { } } } + +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 mut article = Self::new(author.clone(), title.clone(), journal.clone(), date); + + if let Some(volume) = map.get("volume") { + article.volume = Some(volume.clone()); + } + if let Some(number) = map.get("number") { + article.number = Some(number.clone()); + } + if let Some(pages) = map.get("pages") { + article.pages = Some(pages.clone()); + } + + Some(Box::new(article)) + } +} diff --git a/src/bibliography/bib_types/book.rs b/src/bibliography/bib_types/book.rs index 5a7c1d8..732646f 100644 --- a/src/bibliography/bib_types/book.rs +++ b/src/bibliography/bib_types/book.rs @@ -1,4 +1,4 @@ -use crate::bibliography::bib_types::LocalDate; +use crate::utils::date::LocalDate; #[derive(Clone, Debug)] pub struct Book { diff --git a/src/bibliography/bib_types/booklet.rs b/src/bibliography/bib_types/booklet.rs index 17034ef..7924ba4 100644 --- a/src/bibliography/bib_types/booklet.rs +++ b/src/bibliography/bib_types/booklet.rs @@ -1,4 +1,4 @@ -use crate::bibliography::bib_types::LocalDate; +use crate::utils::date::LocalDate; /// A booklet source where only the title can be known #[derive(Clone, Debug)] diff --git a/src/bibliography/bib_types/in_book.rs b/src/bibliography/bib_types/in_book.rs index f04ec5b..448833e 100644 --- a/src/bibliography/bib_types/in_book.rs +++ b/src/bibliography/bib_types/in_book.rs @@ -1,4 +1,4 @@ -use crate::bibliography::bib_types::LocalDate; +use crate::utils::date::LocalDate; /// Source that is part of a book #[derive(Clone, Debug)] diff --git a/src/bibliography/bib_types/in_collection.rs b/src/bibliography/bib_types/in_collection.rs index a5d85ac..a7d0655 100644 --- a/src/bibliography/bib_types/in_collection.rs +++ b/src/bibliography/bib_types/in_collection.rs @@ -1,4 +1,4 @@ -use crate::bibliography::bib_types::LocalDate; +use crate::utils::date::LocalDate; /// A source that is in a collection #[derive(Clone, Debug)] diff --git a/src/bibliography/bib_types/manual.rs b/src/bibliography/bib_types/manual.rs index 7b1b031..2c69ffb 100644 --- a/src/bibliography/bib_types/manual.rs +++ b/src/bibliography/bib_types/manual.rs @@ -1,4 +1,4 @@ -use crate::bibliography::bib_types::LocalDate; +use crate::utils::date::LocalDate; /// A manual entry source #[derive(Clone, Debug)] diff --git a/src/bibliography/bib_types/misc.rs b/src/bibliography/bib_types/misc.rs index 2b19915..6f06106 100644 --- a/src/bibliography/bib_types/misc.rs +++ b/src/bibliography/bib_types/misc.rs @@ -1,4 +1,4 @@ -use crate::bibliography::bib_types::LocalDate; +use crate::utils::date::LocalDate; /// A source that does not fit any of the other types #[derive(Clone, Debug)] diff --git a/src/bibliography/bib_types/mod.rs b/src/bibliography/bib_types/mod.rs index 0cc1e06..33fc986 100644 --- a/src/bibliography/bib_types/mod.rs +++ b/src/bibliography/bib_types/mod.rs @@ -11,7 +11,6 @@ use crate::bibliography::bib_types::thesis::Thesis; use crate::bibliography::bib_types::unpublished::Unpublished; use crate::bibliography::bib_types::website::Website; use crate::bibliography::FromHashMap; -use chrono::{Date, Local}; use std::collections::HashMap; pub mod article; @@ -27,8 +26,6 @@ pub mod thesis; pub mod unpublished; pub mod website; -pub type LocalDate = Date; - /// A type of bibliography entry #[derive(Clone, Debug)] pub enum BibliographyType { @@ -49,7 +46,8 @@ pub enum BibliographyType { impl FromHashMap for BibliographyType { fn from_hash_map(map: &HashMap) -> Option> { if map.contains_key("type") { - match map.get("type").unwrap().to_lowercase() { + match map.get("type").unwrap().as_str() { + "article" => Some(Box::new(Self::Article(*Article::from_hash_map(map)?))), _ => None, } } else { diff --git a/src/bibliography/bib_types/repository.rs b/src/bibliography/bib_types/repository.rs index f6662a3..67530f0 100644 --- a/src/bibliography/bib_types/repository.rs +++ b/src/bibliography/bib_types/repository.rs @@ -1,4 +1,4 @@ -use crate::bibliography::bib_types::LocalDate; +use crate::utils::date::LocalDate; /// A repository source that represents any git repository or similar /// structures @@ -13,7 +13,7 @@ pub struct Repository { } impl Repository { - /// Creates a new repository source with only the mandatory fiels filled + /// Creates a new repository source with only the mandatory fields filled pub fn new(author: String, title: String) -> Self { Self { author, diff --git a/src/bibliography/bib_types/tech_report.rs b/src/bibliography/bib_types/tech_report.rs index 953ff92..4c84e7f 100644 --- a/src/bibliography/bib_types/tech_report.rs +++ b/src/bibliography/bib_types/tech_report.rs @@ -1,4 +1,4 @@ -use crate::bibliography::bib_types::LocalDate; +use crate::utils::date::LocalDate; /// A tech report for example a white paper #[derive(Clone, Debug)] diff --git a/src/bibliography/bib_types/thesis.rs b/src/bibliography/bib_types/thesis.rs index e9fbe27..a62735c 100644 --- a/src/bibliography/bib_types/thesis.rs +++ b/src/bibliography/bib_types/thesis.rs @@ -1,4 +1,4 @@ -use crate::bibliography::bib_types::LocalDate; +use crate::utils::date::LocalDate; /// A thesis source entry #[derive(Clone, Debug)] diff --git a/src/bibliography/bib_types/unpublished.rs b/src/bibliography/bib_types/unpublished.rs index 0c1c057..ceb9d42 100644 --- a/src/bibliography/bib_types/unpublished.rs +++ b/src/bibliography/bib_types/unpublished.rs @@ -1,4 +1,4 @@ -use crate::bibliography::bib_types::LocalDate; +use crate::utils::date::LocalDate; /// A source that is not formally published #[derive(Clone, Debug)] diff --git a/src/bibliography/bib_types/website.rs b/src/bibliography/bib_types/website.rs index 816870a..a3c331b 100644 --- a/src/bibliography/bib_types/website.rs +++ b/src/bibliography/bib_types/website.rs @@ -1,4 +1,4 @@ -use crate::bibliography::bib_types::LocalDate; +use crate::utils::date::LocalDate; /// A website source that can only consists of an url #[derive(Clone, Debug)] diff --git a/src/lib.rs b/src/lib.rs index f410465..ec69652 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,15 @@ pub mod bib_manager; pub mod bibliography; pub mod references; +pub mod utils; #[cfg(test)] mod tests { use crate::bib_manager::BibManager; + use crate::bibliography::bibliography_entry::BibliographyEntry; + use crate::bibliography::FromHashMap; use crate::references::bib_reference::BibRef; + use std::collections::HashMap; #[test] fn it_inserts_and_flattens() { @@ -26,4 +30,18 @@ mod tests { assert_eq!(root_anchor.references().len(), 3) } + + #[test] + fn it_converts_articles() { + let mut map: HashMap = HashMap::new(); + map.insert("key".to_string(), "test_entry".to_string()); + map.insert("type".to_string(), "article".to_string()); + map.insert("author".to_string(), "test".to_string()); + 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()); + map.insert("note".to_string(), "This is a test".to_string()); + + BibliographyEntry::from_hash_map(&map).unwrap(); + } } diff --git a/src/utils/date.rs b/src/utils/date.rs new file mode 100644 index 0000000..57dddbf --- /dev/null +++ b/src/utils/date.rs @@ -0,0 +1,13 @@ +use chrono::{Date, Local}; +use chrono_english::Dialect; + +pub type LocalDate = Date; + +pub fn parse_date(date_str: &str) -> Option { + 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 + } +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs new file mode 100644 index 0000000..1cce2a3 --- /dev/null +++ b/src/utils/mod.rs @@ -0,0 +1 @@ +pub mod date;