diff --git a/Cargo.toml b/Cargo.toml index 4d0a04365fb24a65359e349a1f37187a6d4fe2e9..a327b5d7861e2659fd5e9013c276e9e3aff9fc02 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,7 @@ authors = ["David Mehren <dmehren1@gmail.com>"] bv = "0.7" bio = "0.19.0" id_tree = "1.3.0" -failure = "0.1.1" \ No newline at end of file +failure = "0.1.1" +serde = "1.0.64" +serde_derive = "1.0.64" +bincode = "1.0.0" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 2b18f66d49be140b1ffe53d4fae82f93b6bcd201..e21698b57b98d69000c128653471058f68e2a9c3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,9 @@ extern crate bv; extern crate id_tree; #[macro_use] extern crate failure; +#[macro_use] +extern crate serde_derive; +extern crate bincode; pub mod common; pub mod trees; diff --git a/src/trees/bp_tree.rs b/src/trees/bp_tree.rs index eb4ffcc5f0338a40edfa3583294dad3d6d05cdda..693bce5506e13f8efe65e0228b8e16ec8a9cbe52 100644 --- a/src/trees/bp_tree.rs +++ b/src/trees/bp_tree.rs @@ -1,18 +1,29 @@ +use bincode::{deserialize, serialize}; use bio::data_structures::rank_select::RankSelect; use bv::{BitVec, BitsMut}; use common::succinct_tree::SuccinctTree; -use failure::Error; +use failure::{Error, ResultExt}; use id_tree::Tree; use std::fmt; use std::fmt::Debug; use std::fmt::Formatter; +use std::fs; +use std::fs::File; +use std::io::Write; +#[derive(Serialize, Deserialize)] pub struct BPTree { bits: BitVec<u8>, rankselect: RankSelect, rminmax: String, } +impl PartialEq for BPTree { + fn eq(&self, other: &BPTree) -> bool { + self.bits == other.bits + } +} + impl SuccinctTree<BPTree> for BPTree { fn is_leaf(&self, index: u64) -> bool { unimplemented!() @@ -64,6 +75,19 @@ impl BPTree { rminmax: "foo".to_string(), }) } + + pub fn from_file(path: String) -> Result<BPTree, Error> { + let file = fs::read(path).context("Could not read saved tree.")?; + let tree: BPTree = deserialize(&file).context("Error while deserializing tree.")?; + Ok(tree) + } + + pub fn save_to(&self, path: String) -> Result<(), Error> { + let encoded = serialize(&self).context("Error while serializing tree.")?; + let mut file = File::create(path).context("Could not save tree.")?; + file.write_all(&encoded)?; + Ok(()) + } } #[cfg(test)] @@ -84,7 +108,26 @@ mod tests { #[test] #[should_panic(expected = "ErrorMessage { msg: \"Bit vector not valid.\" }")] fn new_from_bitvec_invalid() { - let mut bitvec = BitVec::new_fill(false, 2); + let bitvec = BitVec::new_fill(false, 2); BPTree::from_bitvec(bitvec.clone()).unwrap(); } + + #[test] + fn save_load() { + let tree = BPTree::stub_create(); + tree.save_to("testdata/bptree.testdata".to_string()) + .unwrap(); + let result = BPTree::from_file("testdata/bptree.testdata".to_string()).unwrap(); + assert_eq!( + tree, result, + "The loaded tree is not equal to the original one." + ); + } + + #[test] + #[should_panic(expected = "Error while deserializing tree.")] + fn load_invaild() { + BPTree::from_file("testdata/bptree_invalid.testdata".to_string()).unwrap(); + } + } diff --git a/testdata/bptree_invalid.testdata b/testdata/bptree_invalid.testdata new file mode 100644 index 0000000000000000000000000000000000000000..4318da13396d0f974a32b7f727f5bf23ac866417 Binary files /dev/null and b/testdata/bptree_invalid.testdata differ