diff --git a/src/data_store/errors.rs b/src/data_store/errors.rs new file mode 100644 index 0000000..6b5f477 --- /dev/null +++ b/src/data_store/errors.rs @@ -0,0 +1,18 @@ +use std::{ + num::{ParseIntError, TryFromIntError}, + string::FromUtf8Error, +}; + +#[derive(Debug)] +pub enum TypeConversionError { + ParseIntError(ParseIntError), + FromUtf8Error(FromUtf8Error), + TryFromIntError(TryFromIntError), + // Add other type cast error variants as needed +} + +#[derive(Debug)] +pub enum ValueError { + TypeConversionImpossible, + TypeConversionError(TypeConversionError), +} diff --git a/src/data_store/implementations/bytes.rs b/src/data_store/implementations/bytes.rs new file mode 100644 index 0000000..4f0cd70 --- /dev/null +++ b/src/data_store/implementations/bytes.rs @@ -0,0 +1,30 @@ +use crate::data_store::errors::ValueError; + +use super::super::{store::KeyValueStore, value_entry::ValueEntry}; +use std::time::{Duration, Instant}; + +impl KeyValueStore { + /// Inserts a Key-Value(in Vec type) pair in the KeyValueStore + pub fn set_bytes(&mut self, key: String, value: Vec, ttl: Option) { + let expiration = Instant::now() + Duration::from_millis(ttl.unwrap_or(self.default_ttl)); + let value_entry = ValueEntry::from_bytes(value, expiration); + self._insert(&key, &value_entry); + } + + /// Gets a Value (in Vec type) associated to the Key in the KeyValueStore + pub fn get_bytes(&self, key: String) -> Option, ValueError>> { + match self._get_or_none_if_expired(&key) { + Some(value_entry) => Some(value_entry.get_value_as_bytes()), + _ => None, + } + } + + /// Removes the Key-Value pair for the given Key in the KeyValueStore + /// and returns the Value (in Vec type) + pub fn pop_bytes(&mut self, key: String) -> Option, ValueError>> { + match self._remove_and_none_if_expired(&key) { + Some(value_entry) => Some(value_entry.get_value_as_bytes()), + _ => None, + } + } +} diff --git a/src/data_store/implementations/hsets.rs b/src/data_store/implementations/hsets.rs new file mode 100644 index 0000000..5827941 --- /dev/null +++ b/src/data_store/implementations/hsets.rs @@ -0,0 +1,172 @@ +use crate::data_store::errors::ValueError; + +use super::super::{store::KeyValueStore, value_entry::ValueEntry}; +use std::{ + collections::HashSet, + time::{Duration, Instant}, +}; + +impl KeyValueStore { + /// Inserts a Key-Value(in HashSet type) pair in the KeyValueStore + pub fn set_hset(&mut self, key: String, value: Vec, ttl: Option) { + let expiration = Instant::now() + Duration::from_millis(ttl.unwrap_or(self.default_ttl)); + let value_entry = ValueEntry::from_set(HashSet::from_iter(value), expiration); + self._insert(&key, &value_entry); + } + + /// Gets a Value (converted to set type) associated to the Key in the KeyValueStore + pub fn get_hset(&self, key: String) -> Option, ValueError>> { + match self._get_or_none_if_expired(&key) { + Some(value_entry) => Some(value_entry.get_value_as_hset()), + _ => None, + } + } + + fn _get_mut_hset(&mut self, key: String) -> Option, ValueError>> { + match self._get_mut_or_none_if_expired(&key) { + Some(value_entry) => match value_entry.get_value_as_mut_hset() { + Ok(hset) => Some(Ok(hset)), + Err(e) => Some(Err(e)), + }, + None => None, + } + } + + /// Removes the Key-Value pair for the given Key in the KeyValueStore + /// and returns the Value (converted to Vec type) + pub fn pop_hset(&mut self, key: String) -> Option, ValueError>> { + self.pop_list(key) + } + + /// Adds an item to the set and returns the cardinality of the set. + pub fn hset_add(&mut self, key: String, value: String) -> Option> { + match self._get_mut_hset(key) { + Some(Ok(hset)) => { + hset.insert(value); + Some(Ok(hset.len())) + } + Some(Err(e)) => Some(Err(e)), + None => None, + } + } + + /// Removes an item from the set and returns the cardinality of the set. + pub fn hset_remove(&mut self, key: String, value: String) -> Option> { + match self._get_mut_hset(key) { + Some(Ok(hset)) => { + hset.remove(&value); + Some(Ok(hset.len())) + } + Some(Err(e)) => Some(Err(e)), + None => None, + } + } + + /// Checks if the item exists in the given hset + pub fn hset_contains(&self, key: String, value: String) -> Option> { + match self.get_hset(key) { + Some(Ok(hset)) => Some(Ok(hset.contains(&value))), + Some(Err(e)) => Some(Err(e)), + None => None, + } + } + + /// Get the intersection between two sets in the data store + pub fn hset_intersection( + &self, + key1: String, + key2: String, + ) -> Option, ValueError>> { + let opt_res_h1 = self.get_hset(key1); + let opt_res_h2 = self.get_hset(key2); + + let h1 = match opt_res_h1 { + Some(Ok(hset1)) => hset1.to_owned(), + Some(Err(e)) => { + return Some(Err(e)); + } + None => HashSet::new(), + }; + + let h2 = match opt_res_h2 { + Some(Ok(hset2)) => hset2.to_owned(), + Some(Err(e)) => { + return Some(Err(e)); + } + None => HashSet::new(), + }; + + Some(Ok(Vec::from_iter( + h1.intersection(&h2).map(|item| item.to_owned()), + ))) + } + + /// Get the intersection between two sets in the data store + pub fn hset_union( + &self, + key1: String, + key2: String, + ) -> Option, ValueError>> { + let opt_res_h1 = self.get_hset(key1); + let opt_res_h2 = self.get_hset(key2); + + let h1 = match opt_res_h1 { + Some(Ok(hset1)) => hset1.to_owned(), + Some(Err(e)) => { + return Some(Err(e)); + } + None => HashSet::new(), + }; + + let h2 = match opt_res_h2 { + Some(Ok(hset2)) => hset2.to_owned(), + Some(Err(e)) => { + return Some(Err(e)); + } + None => HashSet::new(), + }; + + Some(Ok(Vec::from_iter( + h1.union(&h2).map(|item| item.to_owned()), + ))) + } + + /// Get the difference between two sets in the data store + pub fn hset_difference( + &self, + key1: String, + key2: String, + ) -> Option, ValueError>> { + let opt_res_h1 = self.get_hset(key1); + let opt_res_h2 = self.get_hset(key2); + + let h1 = match opt_res_h1 { + Some(Ok(hset1)) => hset1.to_owned(), + Some(Err(e)) => { + return Some(Err(e)); + } + None => HashSet::new(), + }; + + let h2 = match opt_res_h2 { + Some(Ok(hset2)) => hset2.to_owned(), + Some(Err(e)) => { + return Some(Err(e)); + } + None => HashSet::new(), + }; + + Some(Ok(Vec::from_iter( + h1.difference(&h2).map(|item| item.to_owned()), + ))) + } + + /// cardinality of the set + pub fn hset_size(&self, key: String) -> Option> { + match self.get_hset(key) { + Some(Ok(hset)) => Some(Ok(hset.len())), + Some(Err(e)) => Some(Err(e)), + None => None, + } + } +} diff --git a/src/data_store/implementations/integer.rs b/src/data_store/implementations/integer.rs new file mode 100644 index 0000000..9276bf4 --- /dev/null +++ b/src/data_store/implementations/integer.rs @@ -0,0 +1,68 @@ +use crate::data_store::{ + errors::{TypeConversionError, ValueError}, + types::ValueType, +}; + +use super::super::{store::KeyValueStore, value_entry::ValueEntry}; +use std::time::{Duration, Instant}; + +impl KeyValueStore { + /// Inserts a Key-Value(in i64 type) pair in the KeyValueStore + pub fn set_i64(&mut self, key: String, value: i64, ttl: Option) { + let expiration = Instant::now() + Duration::from_millis(ttl.unwrap_or(self.default_ttl)); + let value_entry = ValueEntry::from_i64(value, expiration); + self._insert(&key, &value_entry); + } + + /// Gets a Value (converted to String type) associated to the Key in the KeyValueStore + pub fn get_i64(&self, key: String) -> Option> { + match self._get_or_none_if_expired(&key) { + Some(value_entry) => Some(value_entry.get_value_as_i64()), + _ => None, + } + } + + /// Removes the Key-Value pair for the given Key in the KeyValueStore + /// and returns the Value (converted to i64 type) + pub fn pop_i64(&mut self, key: String) -> Option> { + match self._remove_and_none_if_expired(&key) { + Some(value_entry) => Some(value_entry.get_value_as_i64()), + _ => None, + } + } + + fn _add(&mut self, key: String, value: i64) -> Option> { + if let Some(value_entry) = self._get_mut_or_none_if_expired(&key) { + match value_entry.get_value_as_i64() { + Ok(old_value) => { + let updated_integer_value = old_value + value; + value_entry.value = ValueType::Integer64(updated_integer_value); + Some(Ok(updated_integer_value)) + } + Err(e) => Some(Err(e)), + } + } else { + None + } + } + + /// decrement an existing value associated to key by a certain number. + pub fn decr(&mut self, key: String, by: Option) -> Option> { + match i64::try_from(by.unwrap_or(1)) { + Ok(value) => self._add(key, -value), + Err(e) => Some(Err(ValueError::TypeConversionError( + TypeConversionError::TryFromIntError(e), + ))), + } + } + + /// increment an existing value associated to a key by a certain number. + pub fn incr(&mut self, key: String, by: Option) -> Option> { + match i64::try_from(by.unwrap_or(1)) { + Ok(value) => self._add(key, value), + Err(e) => Some(Err(ValueError::TypeConversionError( + TypeConversionError::TryFromIntError(e), + ))), + } + } +} diff --git a/src/data_store/implementations/lists.rs b/src/data_store/implementations/lists.rs new file mode 100644 index 0000000..3166f84 --- /dev/null +++ b/src/data_store/implementations/lists.rs @@ -0,0 +1,149 @@ +use crate::data_store::errors::ValueError; + +use super::super::{store::KeyValueStore, value_entry::ValueEntry}; +use std::{ + collections::VecDeque, + time::{Duration, Instant}, +}; + +impl KeyValueStore { + /// Inserts a Key-Value(in Vec type) pair in the KeyValueStore + pub fn set_list(&mut self, key: String, value: Vec, ttl: Option) { + let expiration = Instant::now() + Duration::from_millis(ttl.unwrap_or(self.default_ttl)); + let value_entry = ValueEntry::from_list(value, expiration); + self._insert(&key, &value_entry); + } + + /// Gets a Value (converted to Vec type) associated to the Key in the KeyValueStore + pub fn get_list(&self, key: String) -> Option, ValueError>> { + match self._get_or_none_if_expired(&key) { + Some(value_entry) => Some(value_entry.get_value_as_list()), + _ => None, + } + } + + /// Removes the Key-Value pair for the given Key in the KeyValueStore + /// and returns the Value (converted to Vec type) + pub fn pop_list(&mut self, key: String) -> Option, ValueError>> { + match self._remove_and_none_if_expired(&key) { + Some(value_entry) => Some(value_entry.get_value_as_list()), + _ => None, + } + } + + fn _get_deque(&self, key: String) -> Option, ValueError>> { + match self._get_or_none_if_expired(&key) { + Some(value_entry) => match value_entry.get_value_as_deque() { + Ok(deque) => Some(Ok(deque)), + Err(e) => Some(Err(e)), + }, + None => None, + } + } + + fn _get_mut_deque(&mut self, key: String) -> Option, ValueError>> { + match self._get_mut_or_none_if_expired(&key) { + Some(value_entry) => match value_entry.get_value_as_mut_deque() { + Ok(deque) => Some(Ok(deque)), + Err(e) => Some(Err(e)), + }, + None => None, + } + } + + /// Append to the back of a list + pub fn list_pushb(&mut self, key: String, value: String) -> Option> { + match self._get_mut_deque(key) { + Some(Ok(deque)) => { + deque.push_back(value.to_owned()); + Some(Ok(value)) + } + Some(Err(e)) => Some(Err(e)), + None => None, + } + } + + /// Append to the front of a list + pub fn list_pushf(&mut self, key: String, value: String) -> Option> { + match self._get_mut_deque(key) { + Some(Ok(deque)) => { + deque.push_front(value.to_owned()); + Some(Ok(value)) + } + Some(Err(e)) => Some(Err(e)), + None => None, + } + } + + /// pop from the front of a list + pub fn list_popf(&mut self, key: String) -> Option> { + match self._get_mut_deque(key) { + Some(Ok(deque)) => { + let opt_value = deque.pop_front(); + if let Some(value) = opt_value { + Some(Ok(value)) + } else { + None + } + } + Some(Err(e)) => Some(Err(e)), + None => None, + } + } + + /// pop from the back of a list + pub fn list_popb(&mut self, key: String) -> Option> { + match self._get_mut_deque(key) { + Some(Ok(deque)) => { + let opt_value = deque.pop_back(); + if let Some(value) = opt_value { + Some(Ok(value)) + } else { + None + } + } + Some(Err(e)) => Some(Err(e)), + None => None, + } + } + + /// get front of the list + pub fn list_front(&self, key: String) -> Option> { + match self._get_deque(key) { + Some(Ok(deque)) => { + let opt_value = deque.front(); + if let Some(value) = opt_value { + Some(Ok(value.to_owned())) + } else { + None + } + } + Some(Err(e)) => Some(Err(e)), + None => None, + } + } + + /// get back of the list + pub fn list_back(&self, key: String) -> Option> { + match self._get_deque(key) { + Some(Ok(deque)) => { + let opt_value = deque.back(); + if let Some(value) = opt_value { + Some(Ok(value.to_owned())) + } else { + None + } + } + Some(Err(e)) => Some(Err(e)), + None => None, + } + } + /// size of the list + pub fn list_size(&self, key: String) -> Option> { + match self._get_deque(key) { + Some(Ok(deque)) => Some(Ok(deque.len())), + Some(Err(e)) => Some(Err(e)), + None => None, + } + } +} diff --git a/src/data_store/implementations/mod.rs b/src/data_store/implementations/mod.rs new file mode 100644 index 0000000..a819d2b --- /dev/null +++ b/src/data_store/implementations/mod.rs @@ -0,0 +1,5 @@ +mod bytes; +mod hsets; +mod integer; +mod lists; +mod strings; diff --git a/src/data_store/implementations/strings.rs b/src/data_store/implementations/strings.rs new file mode 100644 index 0000000..91e86db --- /dev/null +++ b/src/data_store/implementations/strings.rs @@ -0,0 +1,30 @@ +use crate::data_store::errors::ValueError; + +use super::super::{store::KeyValueStore, value_entry::ValueEntry}; +use std::time::{Duration, Instant}; + +impl KeyValueStore { + /// Inserts a Key-Value(in String type) pair in the KeyValueStore + pub fn set_string(&mut self, key: String, value: String, ttl: Option) { + let expiration = Instant::now() + Duration::from_millis(ttl.unwrap_or(self.default_ttl)); + let value_entry = ValueEntry::from_string(value, expiration); + self._insert(&key, &value_entry); + } + + /// Gets a Value (converted to String type) associated to the Key in the KeyValueStore + pub fn get_string(&self, key: String) -> Option> { + match self._get_or_none_if_expired(&key) { + Some(value_entry) => Some(value_entry.get_value_as_string()), + _ => None, + } + } + + /// Removes the Key-Value pair for the given Key in the KeyValueStore + /// and returns the Value (converted to String type) + pub fn pop_string(&mut self, key: String) -> Option> { + match self._remove_and_none_if_expired(&key) { + Some(value_entry) => Some(value_entry.get_value_as_string()), + _ => None, + } + } +} diff --git a/src/data_store/mod.rs b/src/data_store/mod.rs index 3a8cc95..8fd0a8c 100644 --- a/src/data_store/mod.rs +++ b/src/data_store/mod.rs @@ -1,2 +1,5 @@ +mod errors; +mod implementations; pub mod store; +mod types; mod value_entry; diff --git a/src/data_store/store.rs b/src/data_store/store.rs index 52570c1..ed2cb10 100644 --- a/src/data_store/store.rs +++ b/src/data_store/store.rs @@ -1,14 +1,15 @@ -use super::value_entry::{TypeConversionError, ValueEntry, ValueError, ValueType}; -use std::collections::{HashMap, HashSet, VecDeque}; -use std::time::{Duration, Instant}; +use std::collections::HashMap; +use std::time::Instant; + +use super::value_entry::ValueEntry; /// The main struct of the Key-Value store pub struct KeyValueStore { /// The data is internally stored as a HashMap mapping String keys to a KeyValueEntry struct - _data: HashMap, + pub(super) _data: HashMap, /// The default time to live for each key is set here (globally). - default_ttl: u64, + pub(super) default_ttl: u64, } impl KeyValueStore { @@ -22,11 +23,11 @@ impl KeyValueStore { } } - fn _insert(&mut self, key: &String, value_entry: &ValueEntry) { + pub(super) fn _insert(&mut self, key: &String, value_entry: &ValueEntry) { self._data.insert(key.to_owned(), value_entry.to_owned()); } - fn _remove_and_none_if_expired(&mut self, key: &String) -> Option { + pub(super) fn _remove_and_none_if_expired(&mut self, key: &String) -> Option { if let Some(value_entry) = self._data.remove(key) { if value_entry.is_expired_entry(None) { None @@ -38,7 +39,7 @@ impl KeyValueStore { } } - fn _get_or_none_if_expired(&self, key: &String) -> Option<&ValueEntry> { + pub(super) fn _get_or_none_if_expired(&self, key: &String) -> Option<&ValueEntry> { if let Some(value_entry) = self._data.get(key) { if value_entry.is_expired_entry(None) { None @@ -50,7 +51,7 @@ impl KeyValueStore { } } - fn _get_mut_or_none_if_expired(&mut self, key: &String) -> Option<&mut ValueEntry> { + pub(super) fn _get_mut_or_none_if_expired(&mut self, key: &String) -> Option<&mut ValueEntry> { if let Some(value_entry) = self._data.get_mut(key) { if value_entry.is_expired_entry(None) { None @@ -91,424 +92,13 @@ impl KeyValueStore { } } - /// Inserts a Key-Value(in Vec type) pair in the KeyValueStore - pub fn set_bytes(&mut self, key: String, value: Vec, ttl: Option) { - let expiration = Instant::now() + Duration::from_millis(ttl.unwrap_or(self.default_ttl)); - let value_entry = ValueEntry::from_bytes(value, expiration); - self._insert(&key, &value_entry); - } - - /// Inserts a Key-Value(in String type) pair in the KeyValueStore - pub fn set_string(&mut self, key: String, value: String, ttl: Option) { - let expiration = Instant::now() + Duration::from_millis(ttl.unwrap_or(self.default_ttl)); - let value_entry = ValueEntry::from_string(value, expiration); - self._insert(&key, &value_entry); - } - - /// Inserts a Key-Value(in i64 type) pair in the KeyValueStore - pub fn set_i64(&mut self, key: String, value: i64, ttl: Option) { - let expiration = Instant::now() + Duration::from_millis(ttl.unwrap_or(self.default_ttl)); - let value_entry = ValueEntry::from_i64(value, expiration); - self._insert(&key, &value_entry); - } - - /// Inserts a Key-Value(in Vec type) pair in the KeyValueStore - pub fn set_list(&mut self, key: String, value: Vec, ttl: Option) { - let expiration = Instant::now() + Duration::from_millis(ttl.unwrap_or(self.default_ttl)); - let value_entry = ValueEntry::from_list(value, expiration); - self._insert(&key, &value_entry); - } - - /// Inserts a Key-Value(in HashSet type) pair in the KeyValueStore - pub fn set_hset(&mut self, key: String, value: Vec, ttl: Option) { - let expiration = Instant::now() + Duration::from_millis(ttl.unwrap_or(self.default_ttl)); - let value_entry = ValueEntry::from_set(HashSet::from_iter(value), expiration); - self._insert(&key, &value_entry); - } - - /// Gets a Value (in Vec type) associated to the Key in the KeyValueStore - pub fn get_bytes(&self, key: String) -> Option, ValueError>> { - match self._get_or_none_if_expired(&key) { - Some(value_entry) => Some(value_entry.get_value_as_bytes()), - _ => None, - } - } - - /// Gets a Value (converted to String type) associated to the Key in the KeyValueStore - pub fn get_string(&self, key: String) -> Option> { - match self._get_or_none_if_expired(&key) { - Some(value_entry) => Some(value_entry.get_value_as_string()), - _ => None, - } - } - - /// Gets a Value (converted to String type) associated to the Key in the KeyValueStore - pub fn get_i64(&self, key: String) -> Option> { - match self._get_or_none_if_expired(&key) { - Some(value_entry) => Some(value_entry.get_value_as_i64()), - _ => None, - } - } - - /// Gets a Value (converted to Vec type) associated to the Key in the KeyValueStore - pub fn get_list(&self, key: String) -> Option, ValueError>> { - match self._get_or_none_if_expired(&key) { - Some(value_entry) => Some(value_entry.get_value_as_list()), - _ => None, - } - } - - fn _get_deque(&self, key: String) -> Option, ValueError>> { - match self._get_or_none_if_expired(&key) { - Some(value_entry) => match value_entry.get_value_as_deque() { - Ok(deque) => Some(Ok(deque)), - Err(e) => Some(Err(e)), - }, - None => None, - } - } - - fn _get_mut_deque(&mut self, key: String) -> Option, ValueError>> { - match self._get_mut_or_none_if_expired(&key) { - Some(value_entry) => match value_entry.get_value_as_mut_deque() { - Ok(deque) => Some(Ok(deque)), - Err(e) => Some(Err(e)), - }, - None => None, - } - } - - /// Gets a Value (converted to set type) associated to the Key in the KeyValueStore - pub fn get_hset(&self, key: String) -> Option, ValueError>> { - match self._get_or_none_if_expired(&key) { - Some(value_entry) => Some(value_entry.get_value_as_hset()), - _ => None, - } - } - - fn _get_mut_hset(&mut self, key: String) -> Option, ValueError>> { - match self._get_mut_or_none_if_expired(&key) { - Some(value_entry) => match value_entry.get_value_as_mut_hset() { - Ok(hset) => Some(Ok(hset)), - Err(e) => Some(Err(e)), - }, - None => None, - } - } - /// Removes the Key-Value pair for the given Key in the KeyValueStore pub fn remove(&mut self, key: String) { self._remove_and_none_if_expired(&key); } - /// Removes the Key-Value pair for the given Key in the KeyValueStore - /// and returns the Value (in Vec type) - pub fn pop_bytes(&mut self, key: String) -> Option, ValueError>> { - match self._remove_and_none_if_expired(&key) { - Some(value_entry) => Some(value_entry.get_value_as_bytes()), - _ => None, - } - } - - /// Removes the Key-Value pair for the given Key in the KeyValueStore - /// and returns the Value (converted to String type) - pub fn pop_string(&mut self, key: String) -> Option> { - match self._remove_and_none_if_expired(&key) { - Some(value_entry) => Some(value_entry.get_value_as_string()), - _ => None, - } - } - - /// Removes the Key-Value pair for the given Key in the KeyValueStore - /// and returns the Value (converted to i64 type) - pub fn pop_i64(&mut self, key: String) -> Option> { - match self._remove_and_none_if_expired(&key) { - Some(value_entry) => Some(value_entry.get_value_as_i64()), - _ => None, - } - } - - /// Removes the Key-Value pair for the given Key in the KeyValueStore - /// and returns the Value (converted to Vec type) - pub fn pop_list(&mut self, key: String) -> Option, ValueError>> { - match self._remove_and_none_if_expired(&key) { - Some(value_entry) => Some(value_entry.get_value_as_list()), - _ => None, - } - } - - /// Removes the Key-Value pair for the given Key in the KeyValueStore - /// and returns the Value (converted to Vec type) - pub fn pop_set(&mut self, key: String) -> Option, ValueError>> { - self.pop_list(key) - } - /// Clear all Key-Value pairs from the KeyValueStore pub fn clear(&mut self) { self._data.clear(); } - - fn _add(&mut self, key: String, value: i64) -> Option> { - if let Some(value_entry) = self._get_mut_or_none_if_expired(&key) { - match value_entry.get_value_as_i64() { - Ok(old_value) => { - let updated_integer_value = old_value + value; - value_entry.value = ValueType::Integer64(updated_integer_value); - Some(Ok(updated_integer_value)) - } - Err(e) => Some(Err(e)), - } - } else { - None - } - } - - /// decrement an existing value associated to key by a certain number. - pub fn decr(&mut self, key: String, by: Option) -> Option> { - match i64::try_from(by.unwrap_or(1)) { - Ok(value) => self._add(key, -value), - Err(e) => Some(Err(ValueError::TypeConversionError( - TypeConversionError::TryFromIntError(e), - ))), - } - } - - /// increment an existing value associated to a key by a certain number. - pub fn incr(&mut self, key: String, by: Option) -> Option> { - match i64::try_from(by.unwrap_or(1)) { - Ok(value) => self._add(key, value), - Err(e) => Some(Err(ValueError::TypeConversionError( - TypeConversionError::TryFromIntError(e), - ))), - } - } - - /// Append to the back of a list - pub fn list_pushb(&mut self, key: String, value: String) -> Option> { - match self._get_mut_deque(key) { - Some(Ok(deque)) => { - deque.push_back(value.to_owned()); - Some(Ok(value)) - } - Some(Err(e)) => Some(Err(e)), - None => None, - } - } - - /// Append to the front of a list - pub fn list_pushf(&mut self, key: String, value: String) -> Option> { - match self._get_mut_deque(key) { - Some(Ok(deque)) => { - deque.push_front(value.to_owned()); - Some(Ok(value)) - } - Some(Err(e)) => Some(Err(e)), - None => None, - } - } - - /// pop from the front of a list - pub fn list_popf(&mut self, key: String) -> Option> { - match self._get_mut_deque(key) { - Some(Ok(deque)) => { - let opt_value = deque.pop_front(); - if let Some(value) = opt_value { - Some(Ok(value)) - } else { - None - } - } - Some(Err(e)) => Some(Err(e)), - None => None, - } - } - - /// pop from the back of a list - pub fn list_popb(&mut self, key: String) -> Option> { - match self._get_mut_deque(key) { - Some(Ok(deque)) => { - let opt_value = deque.pop_back(); - if let Some(value) = opt_value { - Some(Ok(value)) - } else { - None - } - } - Some(Err(e)) => Some(Err(e)), - None => None, - } - } - - /// get front of the list - pub fn list_front(&self, key: String) -> Option> { - match self._get_deque(key) { - Some(Ok(deque)) => { - let opt_value = deque.front(); - if let Some(value) = opt_value { - Some(Ok(value.to_owned())) - } else { - None - } - } - Some(Err(e)) => Some(Err(e)), - None => None, - } - } - - /// get back of the list - pub fn list_back(&self, key: String) -> Option> { - match self._get_deque(key) { - Some(Ok(deque)) => { - let opt_value = deque.back(); - if let Some(value) = opt_value { - Some(Ok(value.to_owned())) - } else { - None - } - } - Some(Err(e)) => Some(Err(e)), - None => None, - } - } - - /// Adds an item to the set and returns the cardinality of the set. - pub fn hset_add(&mut self, key: String, value: String) -> Option> { - match self._get_mut_hset(key) { - Some(Ok(hset)) => { - hset.insert(value); - Some(Ok(hset.len())) - } - Some(Err(e)) => Some(Err(e)), - None => None, - } - } - - /// Removes an item from the set and returns the cardinality of the set. - pub fn hset_remove(&mut self, key: String, value: String) -> Option> { - match self._get_mut_hset(key) { - Some(Ok(hset)) => { - hset.remove(&value); - Some(Ok(hset.len())) - } - Some(Err(e)) => Some(Err(e)), - None => None, - } - } - - /// Checks if the item exists in the given hset - pub fn hset_contains(&self, key: String, value: String) -> Option> { - match self.get_hset(key) { - Some(Ok(hset)) => Some(Ok(hset.contains(&value))), - Some(Err(e)) => Some(Err(e)), - None => None, - } - } - - /// Get the intersection between two sets in the data store - pub fn hset_intersection( - &self, - key1: String, - key2: String, - ) -> Option, ValueError>> { - let opt_res_h1 = self.get_hset(key1); - let opt_res_h2 = self.get_hset(key2); - - let h1 = match opt_res_h1 { - Some(Ok(hset1)) => hset1.to_owned(), - Some(Err(e)) => { - return Some(Err(e)); - } - None => HashSet::new(), - }; - - let h2 = match opt_res_h2 { - Some(Ok(hset2)) => hset2.to_owned(), - Some(Err(e)) => { - return Some(Err(e)); - } - None => HashSet::new(), - }; - - Some(Ok(Vec::from_iter( - h1.intersection(&h2).map(|item| item.to_owned()), - ))) - } - - /// Get the intersection between two sets in the data store - pub fn hset_union( - &self, - key1: String, - key2: String, - ) -> Option, ValueError>> { - let opt_res_h1 = self.get_hset(key1); - let opt_res_h2 = self.get_hset(key2); - - let h1 = match opt_res_h1 { - Some(Ok(hset1)) => hset1.to_owned(), - Some(Err(e)) => { - return Some(Err(e)); - } - None => HashSet::new(), - }; - - let h2 = match opt_res_h2 { - Some(Ok(hset2)) => hset2.to_owned(), - Some(Err(e)) => { - return Some(Err(e)); - } - None => HashSet::new(), - }; - - Some(Ok(Vec::from_iter( - h1.union(&h2).map(|item| item.to_owned()), - ))) - } - - /// Get the difference between two sets in the data store - pub fn hset_difference( - &self, - key1: String, - key2: String, - ) -> Option, ValueError>> { - let opt_res_h1 = self.get_hset(key1); - let opt_res_h2 = self.get_hset(key2); - - let h1 = match opt_res_h1 { - Some(Ok(hset1)) => hset1.to_owned(), - Some(Err(e)) => { - return Some(Err(e)); - } - None => HashSet::new(), - }; - - let h2 = match opt_res_h2 { - Some(Ok(hset2)) => hset2.to_owned(), - Some(Err(e)) => { - return Some(Err(e)); - } - None => HashSet::new(), - }; - - Some(Ok(Vec::from_iter( - h1.difference(&h2).map(|item| item.to_owned()), - ))) - } - - /// size of the list - pub fn list_size(&self, key: String) -> Option> { - match self._get_deque(key) { - Some(Ok(deque)) => Some(Ok(deque.len())), - Some(Err(e)) => Some(Err(e)), - None => None, - } - } - - /// cardinality of the set - pub fn hset_size(&self, key: String) -> Option> { - match self.get_hset(key) { - Some(Ok(hset)) => Some(Ok(hset.len())), - Some(Err(e)) => Some(Err(e)), - None => None, - } - } } diff --git a/src/data_store/types.rs b/src/data_store/types.rs new file mode 100644 index 0000000..f8d4aa0 --- /dev/null +++ b/src/data_store/types.rs @@ -0,0 +1,11 @@ +use std::collections::{HashMap, HashSet, VecDeque}; + +#[derive(Clone)] +pub enum ValueType { + Integer64(i64), + Bytes(Vec), + String(String), + Deque(VecDeque), + Set(HashSet), + HashMap(HashMap), +} diff --git a/src/data_store/value_entry.rs b/src/data_store/value_entry.rs index 732b3bf..c95f2b9 100644 --- a/src/data_store/value_entry.rs +++ b/src/data_store/value_entry.rs @@ -1,33 +1,12 @@ use std::{ collections::{vec_deque::VecDeque, HashMap, HashSet}, - num::{ParseIntError, TryFromIntError}, - string::FromUtf8Error, time::Instant, }; -#[derive(Debug)] -pub enum TypeConversionError { - ParseIntError(ParseIntError), - FromUtf8Error(FromUtf8Error), - TryFromIntError(TryFromIntError), - // Add other type cast error variants as needed -} - -#[derive(Debug)] -pub enum ValueError { - TypeConversionImpossible, - TypeConversionError(TypeConversionError), -} - -#[derive(Clone)] -pub enum ValueType { - Integer64(i64), - Bytes(Vec), - String(String), - Deque(VecDeque), - Set(HashSet), - HashMap(HashMap), -} +use super::{ + errors::{TypeConversionError, ValueError}, + types::ValueType, +}; /// Each entry of the Key-Value pair in the Data store is this struct. #[derive(Clone)]