use networking::encryption::*;
use networking::{ArtificePeer};
use std::{
fmt::Debug,
fs::File,
io::{Read, Write},
path::{Path, PathBuf},
string::ToString,
error::Error,
};
use serde::{de::Deserialize,de::DeserializeOwned, ser::Serialize};
pub trait GetPrimaryKey<T: ToString> {
fn get_key(&self) -> T;
}
pub trait Table<'a, A: ToString, T: Debug + Clone + Serialize + Deserialize<'a> + GetPrimaryKey<A>, F: Error + std::marker::Sized>
{
fn create<P: AsRef<Path>>(path: P, password: &[u8]) -> Result<Self, F>
where Self: std::marker::Sized;
fn get<K: ToString>(&self, key: &K) -> Result<T, F>;
fn insert<K: ToString>(&self, peer: &T) -> Result<(), F>;
}
pub trait Entry<'a, T: Debug + Clone + Serialize + Deserialize<'a>, F: std::error::Error + std::marker::Sized> {
fn create<P: AsRef<Path>>(path: P, password: &[u8]) -> Result<Self, F>
where Self: std::marker::Sized;
fn get_value(&self) -> Result<T, Box<dyn std::error::Error>>;
fn save(&self) -> Result<(), Box<dyn std::error::Error>>;
}
pub trait Database<F: Error + std::marker::Sized> {
fn create<P: AsRef<Path>>(root: P) -> Result<Self, F>
where Self: std::marker::Sized;
fn root(&self) -> PathBuf;
fn create_table<
'a,
B: ToString,
A: Debug + Clone + Serialize + Deserialize<'a> + GetPrimaryKey<B>,
T: Table<'a, B, A, F>,
>(
&self,
key: B,
password: &[u8],
) -> Result<T, F>;
fn load_entry<K, T>(&self, key: K, password: &[u8]) -> Result<T, F>
where
K: ToString,
T: Debug + Clone + Serialize + DeserializeOwned;
}
impl GetPrimaryKey<String> for ArtificePeer {
fn get_key(&self) -> String {
self.global_peer_hash()
}
}
pub struct ArtificePeers {
root: String,
password: Vec<u8>,
}
impl Table<'_, String, ArtificePeer, std::io::Error> for ArtificePeers {
fn create<P: AsRef<Path>>(path: P, pass: &[u8]) -> Result<Self, std::io::Error> {
let mut password = Vec::new();
password.extend_from_slice(pass);
Ok(Self {
root: format!("{}", path.as_ref().display()),
password,
})
}
fn get<K: ToString>(&self, key: &K) -> Result<ArtificePeer, std::io::Error> {
let key = key.to_string();
let password = self.password.as_slice();
let mut file = File::open(format!("{}{}.artusr", self.root, key))?;
let mut input = Vec::new();
let mut outbuf = Vec::new();
file.read_to_end(&mut input)?;
decrypt(password, &input, &mut outbuf);
let content = String::from_utf8(outbuf).unwrap();
Ok(serde_json::from_str(&content).unwrap())
}
fn insert<K: ToString>(&self, peer: &ArtificePeer) -> Result<(), std::io::Error>{
let key = peer.get_key();
let password = self.password.as_slice();
let mut file = File::open(format!("{}{}.artusr", self.root, key))?;
let input_vec = serde_json::to_string(peer).unwrap().into_bytes();
let mut outbuf = Vec::new();
encrypt(password, &input_vec, &mut outbuf);
file.write_all(&outbuf)
}
}