use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use std::fmt;
use std::io::{Read, Write};
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: SonicSerdeObject,
pub filepath: PathBuf,
}
#[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(filep: impl Into<PathBuf>) -> Self {
let filepath = filep.into();
let tree: SonicSerdeObject;
if filepath.exists() {
let mut file_obj = std::fs::File::open(filepath.clone()).unwrap();
let mut buf: Vec<u8> = Vec::new();
file_obj.read_to_end(&mut buf).unwrap();
tree = rmp_serde::decode::from_slice(&buf).unwrap()
} else {
tree = SonicSerdeObject::new_map();
}
Self {
tree: tree,
filepath: filepath,
}
}
pub fn contains(&self, key: impl Into<String>) -> bool {
let key_string = key.into();
self.tree.as_map().unwrap().contains_key(&key_string.into())
}
pub fn get(&self, key: impl Into<String>) -> SonicObject {
let key_string = key.into();
let u8_vec: Vec<u8> = self.tree.as_map().unwrap().get(&key_string.into()).unwrap().clone().as_vecu8().unwrap();
let p: SonicSerdeObject = rmp_serde::decode::from_slice(&u8_vec).unwrap();
SonicObject::new(p)
}
pub fn insert(&mut self, key: impl Into<String>, val: impl Into<SonicSerdeObject>) -> () {
let value = val.into();
let key_string = key.into();
let new_vec = rmp_serde::encode::to_vec(&value).unwrap();
self.tree.insert(key_string, SonicSerdeObject::VecU8(new_vec));
self.flush();
}
pub fn flush(&mut self) -> () {
if self.filepath.exists() {
std::fs::remove_file(self.filepath.clone()).unwrap();
}
let mut file_obj = std::fs::File::create(self.filepath.clone()).unwrap();
file_obj.write_all(&rmp_serde::encode::to_vec(&self.tree).unwrap()).unwrap();
}
}