bibliographix/
bib_manager.rs1use crate::bibliography::bibliography_dict::BibliographyDictionary;
2use crate::bibliography::bibliography_entry::{BibliographyEntry, BibliographyEntryReference};
3use crate::bibliography::keys::K_KEY;
4use crate::bibliography::FromHashMap;
5use crate::references::anchor::BibListAnchor;
6use parking_lot::Mutex;
7use std::collections::HashMap;
8use std::io;
9use std::io::BufRead;
10use std::iter::FromIterator;
11use std::sync::Arc;
12use toml::Value;
13
14#[derive(Clone, Debug)]
17pub struct BibManager {
18 root_ref_anchor: Arc<Mutex<BibListAnchor>>,
19 entry_dictionary: Arc<Mutex<BibliographyDictionary>>,
20}
21
22impl BibManager {
23 pub fn new() -> Self {
25 Self {
26 root_ref_anchor: Arc::new(Mutex::new(BibListAnchor::new())),
27 entry_dictionary: Arc::new(Mutex::new(BibliographyDictionary::new())),
28 }
29 }
30
31 pub fn root_ref_anchor(&self) -> Arc<Mutex<BibListAnchor>> {
33 Arc::clone(&self.root_ref_anchor)
34 }
35
36 pub fn create_child(&self) -> BibManager {
38 let anchor = self.root_ref_anchor.lock().create_anchor();
39 let entry_dict = Arc::clone(&self.entry_dictionary);
40
41 Self {
42 entry_dictionary: entry_dict,
43 root_ref_anchor: anchor,
44 }
45 }
46
47 pub fn entry_dictionary(&self) -> Arc<Mutex<BibliographyDictionary>> {
49 Arc::clone(&self.entry_dictionary)
50 }
51
52 pub fn assign_entries_to_references(&self) {
54 let entry_dict = self.entry_dictionary.lock();
55 let mut root_anchor = self.root_ref_anchor.lock();
56 root_anchor.flatten();
57 let entries = root_anchor.references();
58 entries.iter().for_each(|e| {
59 if let Some(bib) = entry_dict.get(e.key()) {
60 e.anchor().lock().entry = Some(bib)
61 }
62 })
63 }
64
65 pub fn get_entry_list_by_occurrence(&self) -> Vec<BibliographyEntryReference> {
67 let mut entries = Vec::new();
68 let mut inserted_keys = Vec::new();
69 let entry_dict = self.entry_dictionary.lock();
70
71 for bib_ref in self.root_ref_anchor.lock().references() {
72 if let Some(bib_entry) = entry_dict.get(bib_ref.key()) {
73 if !inserted_keys.contains(bib_ref.key()) {
74 entries.push(bib_entry);
75 inserted_keys.push(bib_ref.key().clone())
76 }
77 }
78 }
79
80 entries
81 }
82
83 pub fn read_bib_file(&self, reader: &mut impl BufRead) -> io::Result<()> {
85 let mut contents = String::new();
86 reader.read_to_string(&mut contents)?;
87 let bib_content = contents.parse::<Value>()?;
88 let mut entry_dict = self.entry_dictionary.lock();
89
90 if let Some(table) = bib_content.as_table() {
91 let mut entries = table
92 .iter()
93 .filter_map(|(k, v)| {
94 let entry_iter = v
95 .as_table()?
96 .iter()
97 .filter_map(|(k, v)| Some((k.clone(), v.as_str()?.to_string())));
98
99 let mut entry_map: HashMap<String, String> = HashMap::from_iter(entry_iter);
100
101 entry_map.insert(K_KEY.to_string(), k.clone());
102
103 Some(*BibliographyEntry::from_hash_map(&entry_map).ok()?)
104 })
105 .collect::<Vec<BibliographyEntry>>();
106
107 while let Some(entry) = entries.pop() {
108 entry_dict.insert(entry)
109 }
110 }
111
112 Ok(())
113 }
114}