Add BibRef manager, entries and anchors

main
trivernis 4 years ago
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…
Cancel
Save