Add BibRef manager, entries and anchors
parent
445a577a1e
commit
4139c98917
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DiscordProjectSettings">
|
||||
<option name="show" value="PROJECT_FILES" />
|
||||
</component>
|
||||
</project>
|
@ -1,7 +1,21 @@
|
||||
pub mod references;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::references::reference_manager::BibRefManager;
|
||||
use crate::references::bib_reference::BibRef;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
assert_eq!(2 + 2, 4);
|
||||
fn it_inserts_and_flattens() {
|
||||
let manager = BibRefManager::new();
|
||||
let root_anchor = manager.root_anchor();
|
||||
let mut root_anchor = root_anchor.lock().unwrap();
|
||||
root_anchor.insert(BibRef::new("test".to_string()));
|
||||
let child_anchor = root_anchor.create_anchor();
|
||||
child_anchor.lock().unwrap().insert(BibRef::new("test2".to_string()));
|
||||
child_anchor.lock().unwrap().insert(BibRef::new("test3".to_string()));
|
||||
root_anchor.flatten();
|
||||
|
||||
assert_eq!(root_anchor.references().len(), 3)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,64 @@
|
||||
use crate::references::bib_reference::BibRef;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
/// A bib list anchor that can be used to concurrently insert entries into a list
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BibListAnchor {
|
||||
entries: Vec<BibListEntry>,
|
||||
}
|
||||
|
||||
/// Enum that represents a single entry of a bib list
|
||||
#[derive(Clone, Debug)]
|
||||
enum BibListEntry {
|
||||
Ref(BibRef),
|
||||
Anchor(Arc<Mutex<BibListAnchor>>),
|
||||
}
|
||||
|
||||
impl BibListAnchor {
|
||||
/// Creates a new empty BibListAnchor.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
entries: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Inserts a reference at the current position
|
||||
pub fn insert(&mut self, bib_ref: BibRef) {
|
||||
self.entries.push(BibListEntry::Ref(bib_ref))
|
||||
}
|
||||
|
||||
/// Creates a new anchor at the current position and inserts it into the entry vec.
|
||||
pub fn create_anchor(&mut self) -> Arc<Mutex<BibListAnchor>> {
|
||||
let anchor = Arc::new(Mutex::new(BibListAnchor::new()));
|
||||
self.entries.push(BibListEntry::Anchor(Arc::clone(&anchor)));
|
||||
|
||||
anchor
|
||||
}
|
||||
|
||||
/// Flattens the inner entry structure by inserting the elements of child anchors for every
|
||||
/// anchor in the vector
|
||||
pub fn flatten(&mut self) {
|
||||
let mut new_entries = Vec::with_capacity(self.entries.len());
|
||||
self.entries.iter_mut().for_each(|e| {
|
||||
match e {
|
||||
BibListEntry::Anchor(a) => {
|
||||
let mut anchor = a.lock().unwrap();
|
||||
anchor.flatten();
|
||||
new_entries.append(&mut anchor.entries);
|
||||
}
|
||||
BibListEntry::Ref(bib_ref) => new_entries.push(BibListEntry::Ref(bib_ref.clone()))
|
||||
}
|
||||
});
|
||||
|
||||
self.entries = new_entries;
|
||||
}
|
||||
|
||||
/// Returns all references that are contained in the entry list
|
||||
pub fn references(&self) -> Vec<BibRef> {
|
||||
self.entries.iter().filter_map(|e| if let BibListEntry::Ref(r) = e {
|
||||
Some(r.clone())
|
||||
} else {
|
||||
None
|
||||
}).collect()
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BibRef {
|
||||
key: String,
|
||||
}
|
||||
|
||||
impl BibRef {
|
||||
/// Creates a new BibRef with a given key
|
||||
pub fn new(key: String) -> Self {
|
||||
Self {
|
||||
key
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
pub mod reference_manager;
|
||||
pub mod bib_reference;
|
||||
pub mod anchor;
|
@ -0,0 +1,23 @@
|
||||
use std::sync::{Arc, Mutex};
|
||||
use crate::references::anchor::BibListAnchor;
|
||||
|
||||
/// The root manager for references that should be used for further reference operations that
|
||||
/// go beyond insertion.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BibRefManager {
|
||||
root_anchor: Arc<Mutex<BibListAnchor>>,
|
||||
}
|
||||
|
||||
impl BibRefManager {
|
||||
/// Creates a new BibRefManager with an empty root anchor
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
root_anchor: Arc::new(Mutex::new(BibListAnchor::new()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the BibRefManagers root anchor that.
|
||||
pub fn root_anchor(&self) -> Arc<Mutex<BibListAnchor>> {
|
||||
Arc::clone(&self.root_anchor)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue