summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2021-04-04 14:00:21 +0200
committerMatthias Beyer <mail@beyermatthias.de>2021-04-04 14:05:25 +0200
commit9bf57ebad51b8e1b21bcdba47e9536f0e17880a2 (patch)
tree42527fdfdf3835f8a11787175564174c6cb926f7 /src
parent080771bc233c25e067706e67cba2becbc0748980 (diff)
Implement branching
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Diffstat (limited to 'src')
-rw-r--r--src/async_dag.rs51
-rw-r--r--src/test_impl.rs7
2 files changed, 57 insertions, 1 deletions
diff --git a/src/async_dag.rs b/src/async_dag.rs
index f9f5072..cc0a196 100644
--- a/src/async_dag.rs
+++ b/src/async_dag.rs
@@ -107,6 +107,20 @@ impl<Id, N, Backend> AsyncDag<Id, N, Backend>
self.head = id.clone();
Ok(id)
}
+
+ /// Branch from the current head.
+ ///
+ /// This function creates a new AsyncDag object with the same backend (thus the backend must be
+ /// `Clone` in this case).
+ pub fn branch(&self) -> AsyncDag<Id, N, Backend>
+ where Backend: Clone
+ {
+ AsyncDag {
+ head: self.head.clone(),
+ backend: self.backend.clone(),
+ _node: std::marker::PhantomData,
+ }
+ }
}
@@ -302,5 +316,42 @@ mod tests {
assert_eq!(dag.backend.0[1].as_ref().unwrap().parents[0], test::Id(0));
}
+ #[test]
+ fn test_branch() {
+ let mut dag = {
+ let head = test::Node {
+ id: test::Id(0),
+ parents: vec![],
+ data: 42,
+ };
+ let b = test::Backend(vec![Some(head.clone())]);
+ let dag = tokio_test::block_on(AsyncDag::new(b, head));
+ assert!(dag.is_ok());
+ dag.unwrap()
+ };
+
+ let branched = dag.branch();
+
+ {
+ assert_eq!(dag.backend.0.len(), 1);
+ assert_eq!(dag.head, test::Id(0));
+ let new_head = test::Node {
+ id: test::Id(1),
+ parents: vec![test::Id(0)],
+ data: 43,
+ };
+
+ let id = tokio_test::block_on(dag.update_head(new_head));
+ assert!(id.is_ok());
+ let id = id.unwrap();
+
+ assert_eq!(dag.backend.0.len(), 2);
+ assert_eq!(dag.head, test::Id(1));
+ }
+
+ assert_eq!(branched.backend.0.len(), 1);
+ assert_eq!(branched.head, test::Id(0));
+ }
+
}
diff --git a/src/test_impl.rs b/src/test_impl.rs
index da86543..ae7ce0c 100644
--- a/src/test_impl.rs
+++ b/src/test_impl.rs
@@ -31,7 +31,12 @@ impl crate::Node for Node {
}
}
-#[derive(Debug)]
+/// The backend for the tests
+///
+/// This is `Clone` because we can test branching only with a clonable backend.
+/// A real backend would not implement the storage itself, but rather a way to retrieve the data
+/// from some storage mechansim (think IPFS), and thus `Clone`ing a backend is nothing esotheric.
+#[derive(Clone, Debug)]
pub struct Backend(pub(crate) Vec<Option<Node>>);
#[async_trait]