use acid_store::repo::Commit;
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use acid_store::repo::{OpenOptions, value::ValueRepo, OpenMode};
use acid_store::store::{DirectoryConfig};
use thiserror::Error;
use std::fmt;
use sonic_serde_object::SonicSerdeObject;
#[derive(Serialize, Eq, PartialEq, Deserialize, Debug, Clone)]
pub struct SonicObject {
pub value: SonicSerdeObject,
spot: usize
}
pub struct SonicPersistObject {
pub tree: ValueRepo<String>,
}
#[derive(Debug, Error)]
pub enum SonicObjectError {
KeyError(String),
IndexError(String),
}
impl fmt::Display for SonicObjectError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::IndexError(z) => {
write!(f, "{}", z)
},
Self::KeyError(z) => {
write!(f, "{}", z)
}
}
}
}
impl SonicObject {
pub fn new(value: impl Into<SonicSerdeObject>) -> Self {
let spot: usize = 0;
let v = value.into();
Self {
value: v,
spot: spot,
}
}
pub fn collectvec(&self) -> Vec<Self> {
let x = self.clone();
x.collect::<Vec<Self>>()
}
pub fn get(&self, key: impl Into<SonicSerdeObject>) -> Result<SonicObject, SonicObjectError> {
let keyclone = key.into();
match self.value.as_map().unwrap().get(&keyclone.clone()) {
Some(a) => {
return Ok(SonicObject::new(a.clone()));
},
None => {
return Err(SonicObjectError::KeyError(format!("No such key {:?}", keyclone.clone())));
}
}
}
pub fn contains(&self, key: impl Into<SonicSerdeObject>) -> bool {
self.value.as_map().unwrap().contains_key(&key.into())
}
pub fn keys(&self) -> Vec<SonicSerdeObject> {
self.value.as_map().unwrap().keys().collect::<Vec<&SonicSerdeObject>>().into_iter().map(|z| z.clone()).collect()
}
pub fn insert(&mut self, key: impl Into<SonicSerdeObject>, value: impl Into<SonicSerdeObject>) -> () {
let mut val = self.value.as_map().unwrap();
val.insert(key.into(), value.into());
self.value = SonicSerdeObject::Map(val);
}
pub fn replace_index_with(&mut self, index: usize, value: impl Into<SonicSerdeObject>) {
let mut vvalue = self.value.as_vec().unwrap();
vvalue.remove(index);
vvalue.insert(index, value.into());
}
pub fn push(&mut self, value: impl Into<SonicSerdeObject>) -> () {
let mut svalue = self.value.as_vec().unwrap();
svalue.push(value.into());
self.value = SonicSerdeObject::Vec(svalue);
}
pub fn remove(&mut self, key: impl Into<SonicSerdeObject>) -> () {
let mut svalue = self.value.as_map().unwrap();
svalue.remove(&key.into());
self.value = SonicSerdeObject::Map(svalue);
}
pub fn getindex(&self, index: usize) -> Result<SonicObject, SonicObjectError> {
match self.value.as_vec().unwrap().get(index) {
Some(a) => {
return Ok(SonicObject::new(a.clone()))
},
None => {
return Err(SonicObjectError::IndexError("Index out of range".to_string()));
}
}
}
pub fn getindexvalue(&self, index: usize) -> Result<SonicSerdeObject, SonicObjectError> {
match self.value.as_vec().unwrap().get(index) {
Some(a) => {
return Ok(a.clone());
},
None => {
return Err(SonicObjectError::IndexError("Index out of range".to_string()))
}
}
}
pub fn removeindex(&mut self, index: usize) -> () {
let mut svalue = self.value.as_vec().unwrap();
svalue.remove(index);
self.value = SonicSerdeObject::Vec(svalue);
}
pub fn getvalue(&mut self, key: impl Into<SonicSerdeObject>) -> Result<SonicSerdeObject, SonicObjectError> {
let keyclone = key.into();
match self.value.as_map().unwrap().get(&keyclone.clone()) {
Some(a) => {
return Ok(a.clone());
},
None => {
return Err(SonicObjectError::KeyError(format!("No such key {:?}", keyclone.clone())));
}
}
}
}
impl Iterator for SonicObject {
type Item = SonicObject;
fn next(&mut self) -> Option<SonicObject> {
if self.value.is_vec() {
let val = self.value.as_vec().unwrap();
if self.spot == val.len() {
return None
} else {
self.spot = self.spot + 1;
return Some(SonicObject::new(val[self.spot - 1].clone()))
}
} else {
None
}
}
}
impl SonicPersistObject {
pub fn new(filepath: PathBuf) -> Self {
let tree = OpenOptions::new().mode(OpenMode::Create).open(&DirectoryConfig{ path: filepath }).unwrap(); Self {
tree: tree,
}
}
pub fn contains(&self, key: &str) -> bool {
self.tree.contains(key)
}
pub fn get(&self, key: &str) -> SonicObject {
let u8_vec: Vec<u8> = self.tree.get(&key.to_string()).unwrap();
let p: SonicSerdeObject = rmp_serde::decode::from_slice(&u8_vec).unwrap();
SonicObject::new(p)
}
pub fn insert(&mut self, key: &str, value: impl Into<SonicSerdeObject>) -> () {
let new_vec = rmp_serde::encode::to_vec(&value.into()).unwrap();
self.tree.insert(key.to_string(), &new_vec).unwrap();
self.tree.commit().unwrap();
}
pub fn flush(&mut self) -> () {
self.tree.commit().unwrap();
}
}
pub fn getemptyvalue() -> Value {
let data = r#"{}"#;
let v: Value = serde_json::from_str(data).unwrap();
v
}