diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2021-04-04 14:00:21 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2021-04-04 14:05:25 +0200 |
commit | 9bf57ebad51b8e1b21bcdba47e9536f0e17880a2 (patch) | |
tree | 42527fdfdf3835f8a11787175564174c6cb926f7 /src | |
parent | 080771bc233c25e067706e67cba2becbc0748980 (diff) |
Implement branching
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Diffstat (limited to 'src')
-rw-r--r-- | src/async_dag.rs | 51 | ||||
-rw-r--r-- | src/test_impl.rs | 7 |
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] |