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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use crate::references::reference_manager::BibRefManager;
|
||||||
|
use crate::references::bib_reference::BibRef;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_works() {
|
fn it_inserts_and_flattens() {
|
||||||
assert_eq!(2 + 2, 4);
|
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