diff options
author | Katharina Fey <kookie@spacekookie.de> | 2018-06-11 23:08:55 +0200 |
---|---|---|
committer | Katharina Fey <kookie@spacekookie.de> | 2018-06-11 23:08:55 +0200 |
commit | 17e4f9d4d03dc739a77ab07e59bbb1e9420c25ee (patch) | |
tree | 75feebe2509b9ddefea66123405b7f0b5cce4bd1 | |
parent | 1449971d229c9e5ec2f2dd7589db1d65129754ec (diff) |
Fixing a bug in the vault API, implementing more file
-rw-r--r-- | lockchain-core/src/meta.rs | 12 | ||||
-rw-r--r-- | lockchain-core/src/traits.rs | 4 | ||||
-rw-r--r-- | lockchain-files/examples/create.rs | 17 | ||||
-rw-r--r-- | lockchain-files/src/fs.rs | 42 | ||||
-rw-r--r-- | lockchain-files/src/lib.rs | 30 |
5 files changed, 69 insertions, 36 deletions
diff --git a/lockchain-core/src/meta.rs b/lockchain-core/src/meta.rs index a602e48..fa7fa81 100644 --- a/lockchain-core/src/meta.rs +++ b/lockchain-core/src/meta.rs @@ -33,10 +33,22 @@ pub struct MetaDomain { } impl MetaDomain { + /// Create a new domain space struct + pub fn new<S>(name: S) -> Self + where + S: Into<String>, + { + Self { + name: name.into(), + body: HashMap::new(), + } + } + /// Return the domain name for easy comparison pub fn name(&self) -> &str { &self.name } + /// Get the number of items in this domain pub fn size(&self) -> usize { self.body.len() diff --git a/lockchain-core/src/traits.rs b/lockchain-core/src/traits.rs index 671843d..5a26763 100644 --- a/lockchain-core/src/traits.rs +++ b/lockchain-core/src/traits.rs @@ -11,9 +11,9 @@ //! compilation work without external crates but not calling //! functions at runtime. +use meta::MetaDomain; use record::{EncryptedBody, Header, Payload, Record}; use serde::{de::DeserializeOwned, Serialize}; -use meta::MetaDomain; use base64; use serde_json::{self, Error as SerdeError}; @@ -112,7 +112,7 @@ where /// returned with a single pull request fn meta_add_domain(&mut self, domain: &str) -> Option<()>; /// Returns all records from a meta domain - fn meta_pull_domain(&mut self, domain: &str) -> Option<Vec<MetaDomain>>; + fn meta_pull_domain(&mut self, domain: &str) -> Option<MetaDomain>; /// Set the value of a field inside a domain. Field names **must not** collide fn meta_set(&mut self, domain: &str, name: &str, data: Payload) -> Option<()>; /// Get the value of a (unique) field inside a domain diff --git a/lockchain-files/examples/create.rs b/lockchain-files/examples/create.rs index d672e26..f6ecb8e 100644 --- a/lockchain-files/examples/create.rs +++ b/lockchain-files/examples/create.rs @@ -1,9 +1,9 @@ extern crate lockchain_core as lcc; extern crate lockchain_files as files; -use lcc::{Record, EncryptedBody}; -use lcc::traits::Vault; use files::DataVault; +use lcc::traits::Vault; +use lcc::{EncryptedBody, Payload, Record}; use std::env; fn main() { @@ -11,8 +11,17 @@ fn main() { let path = env::args().nth(1).unwrap(); let name = env::args().nth(2).unwrap(); - let vault: DataVault<EncryptedBody> = DataVault::new(&name, &path); + let mut vault: DataVault<EncryptedBody> = DataVault::new(&name, &path); + vault.meta_add_domain("userstore").unwrap(); + vault + .meta_set( + "userstore", + "spacekookie", + Payload::Text("<access token here>".into()), + ) + .unwrap(); + vault.sync(); } else { eprintln!("Usage: create <path> <name> [FLAGS] (there are no flags)") } -}
\ No newline at end of file +} diff --git a/lockchain-files/src/fs.rs b/lockchain-files/src/fs.rs index 7d71a82..1112733 100644 --- a/lockchain-files/src/fs.rs +++ b/lockchain-files/src/fs.rs @@ -26,6 +26,16 @@ pub enum FileType { Checksum, } +macro_rules! file_ending { + ($type:expr) => { + match $type { + FileType::Record => "record", + FileType::Metadata => "meta", + _ => "dat", + } + }; +} + impl Filesystem { pub fn create(path: &str, name: &str) -> Filesystem { let mut buffer = PathBuf::new(); @@ -70,37 +80,17 @@ impl Filesystem { pub fn pull<T: AutoEncoder>(&self, types: FileType, id: &str) -> Result<T, Box<Error>> { Ok(T::decode( - &File::open(self.root.join(&format!( - "{}.{}", - id, - match types { - FileType::Record => "record", - _ => "dat", - } - )))?.get_string()?, + &File::open(self.root.join(&format!("{}.{}", id, file_ending!(types))))?.get_string()?, )?) } - pub fn sync<T: AutoEncoder>( - &self, - data: &HashMap<String, T>, - types: FileType, - ) -> Result<(), Box<Error>> { + pub fn sync<T>(&self, data: &HashMap<String, T>, types: FileType) -> Result<(), Box<Error>> + where + T: AutoEncoder, + { data.into_iter() .map(|(k, v)| (k, v.encode().ok())) - .map(|(k, v)| { - ( - self.root.join(format!( - "{}.{}", - k, - match types { - FileType::Record => "record", - _ => "dat", - } - )), - v, - ) - }) + .map(|(k, v)| (self.root.join(format!("{}.{}", k, file_ending!(types))), v)) .filter(|(_, v)| v.is_some()) .map(|(k, v)| (k, v.unwrap())) .map(|(path, data): (PathBuf, String)| (OO::new().write(true).open(path), data)) diff --git a/lockchain-files/src/lib.rs b/lockchain-files/src/lib.rs index b9e03a0..3e18812 100644 --- a/lockchain-files/src/lib.rs +++ b/lockchain-files/src/lib.rs @@ -6,7 +6,7 @@ extern crate lockchain_core as lcc; use lcc::traits::{Body, Vault}; -use lcc::{Payload, Record, MetaDomain}; +use lcc::{MetaDomain, Payload, Record}; use std::collections::HashMap; mod fs; @@ -15,6 +15,7 @@ use fs::{FileType, Filesystem}; /// Represents a vault on disk pub struct DataVault<T: Body> { records: HashMap<String, Record<T>>, + metadata: HashMap<String, MetaDomain>, fs: Filesystem, } @@ -30,6 +31,7 @@ impl<T: Body> Vault<T> for DataVault<T> { fn new(name: &str, location: &str) -> DataVault<T> { Self { records: HashMap::new(), + metadata: HashMap::new(), fs: Filesystem::create(location, name), }.initialize() } @@ -37,6 +39,8 @@ impl<T: Body> Vault<T> for DataVault<T> { /// Caches all files from disk to memory fn fetch(&mut self) { self.records.clear(); + self.metadata.clear(); + self.fs .fetch::<Record<T>>(FileType::Record) .unwrap() @@ -45,6 +49,15 @@ impl<T: Body> Vault<T> for DataVault<T> { .for_each(|x| { self.records.insert(x.0, x.1); }); + + self.fs + .fetch::<MetaDomain>(FileType::Metadata) + .unwrap() + .into_iter() + .map(|rec| (rec.name().into(), rec)) + .for_each(|x| { + self.metadata.insert(x.0, x.1); + }); } /// Make sure a single record is loaded @@ -60,6 +73,10 @@ impl<T: Body> Vault<T> for DataVault<T> { self.fs .sync::<Record<T>>(&self.records, FileType::Record) .unwrap(); + + self.fs + .sync::<MetaDomain>(&self.metadata, FileType::Metadata) + .unwrap(); } fn get_record(&self, name: &str) -> Option<&Record<T>> { @@ -88,11 +105,16 @@ impl<T: Body> Vault<T> for DataVault<T> { } fn meta_add_domain(&mut self, domain: &str) -> Option<()> { - None + if self.metadata.contains_key(domain) { + None + } else { + self.metadata.insert(domain.into(), MetaDomain::new(domain)); + Some(()) + } } - fn meta_pull_domain(&mut self, domain: &str) -> Option<Vec<MetaDomain>> { - None + fn meta_pull_domain(&mut self, domain: &str) -> Option<MetaDomain> { + self.metadata.get(domain) } fn meta_set(&mut self, domain: &str, name: &str, data: Payload) -> Option<()> { |