use meta::{MetaDomain, VaultMetadata};
use record::{EncryptedBody, Header, Payload, Record};
use serde::{de::DeserializeOwned, Serialize};
use base64;
use serde_json::{self, Error as SerdeError};
use std::error::Error;
pub trait Body: DeserializeOwned + Serialize + Send {
fn get_field(&self, key: &str) -> Option<&Payload>;
fn set_field(&mut self, key: &str, value: Payload) -> Option<()>;
fn flatten(&mut self) -> Option<()>;
}
pub trait LoadRecord<T: Body> {
fn header() -> Header {
unimplemented!()
}
fn body() -> T {
unimplemented!()
}
}
pub trait Encryptable: AutoEncoder {}
pub trait EncryptionHandler<T>
where
T: Encryptable + AutoEncoder + Body,
{
fn encrypt(&mut self, item: T) -> EncryptedBody;
fn decrypt(&mut self, item: EncryptedBody) -> Option<T>;
}
pub trait FileIO: AutoEncoder {
fn load(path: &str) -> Result<Self, Box<Error>> {
use std::fs;
fs::read_to_string(path)
.and_then(|s| Self::decode(&s).map_err(|e| e.into()))
.map_err(|e| e.into())
}
fn save(&self, path: &str) -> Result<(), Box<Error>> {
use std::fs::OpenOptions;
use std::io::Write;
let mut file = OpenOptions::new().write(true).create(true).open(path)?;
let content = self.encode()?;
file.write_all(content.as_bytes())?;
Ok(())
}
}
pub trait Vault<T>: Send
where
T: Body,
{
fn new(name: &str, location: &str) -> Self;
fn metadata(&self) -> VaultMetadata;
fn fetch(&mut self);
fn pull(&mut self, name: &str);
fn sync(&mut self);
fn get_record(&self, name: &str) -> Option<&Record<T>>;
fn contains(&self, name: &str) -> bool;
fn add_record(&mut self, key: &str, category: &str, tags: Vec<&str>);
fn delete_record(&mut self, record: &str) -> Option<Record<T>>;
fn add_data(&mut self, record: &str, key: &str, data: Payload) -> Option<()>;
fn get_data(&self, record: &str, key: &str) -> Option<&Payload>;
fn meta_add_domain(&mut self, domain: &str) -> Option<()>;
fn meta_pull_domain(&self, domain: &str) -> Option<&MetaDomain>;
fn meta_push_domain(&mut self, domain: MetaDomain) -> Option<()>;
fn meta_set(&mut self, domain: &str, name: &str, data: Payload) -> Option<()>;
fn meta_get(&mut self, domain: &str, name: &str) -> Option<Payload>;
fn meta_exists(&self, domain: &str) -> bool;
}
pub trait AutoEncoder: Serialize + DeserializeOwned {
fn encode(&self) -> Result<String, SerdeError> {
serde_json::to_string_pretty(self)
}
fn decode(s: &str) -> Result<Self, SerdeError> {
serde_json::from_str(s)
}
}
pub trait Base64AutoEncoder {
fn to_base64(&self) -> String;
fn from_base64(base64: &str) -> String;
}
impl Base64AutoEncoder for String {
fn to_base64(&self) -> String {
base64::encode(self.as_bytes())
}
fn from_base64(base64: &str) -> String {
String::from_utf8(base64::decode(base64).unwrap()).unwrap()
}
}
impl Base64AutoEncoder for Vec<u8> {
fn to_base64(&self) -> String {
base64::encode(self)
}
fn from_base64(base64: &str) -> String {
String::from_utf8(base64::decode(base64).unwrap()).unwrap()
}
}