#![allow(dead_code)]
use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq)]
pub enum KvValue {
Int(i64),
Float(f64),
Text(String),
Bool(bool),
Bytes(Vec<u8>),
}
#[derive(Debug, Default, Clone)]
pub struct KeyValueStore {
data: HashMap<String, KvValue>,
}
impl KeyValueStore {
pub fn new() -> Self {
KeyValueStore { data: HashMap::new() }
}
pub fn set(&mut self, key: impl Into<String>, value: KvValue) {
self.data.insert(key.into(), value);
}
pub fn get(&self, key: &str) -> Option<&KvValue> {
self.data.get(key)
}
pub fn delete(&mut self, key: &str) -> bool {
self.data.remove(key).is_some()
}
pub fn contains(&self, key: &str) -> bool {
self.data.contains_key(key)
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn clear(&mut self) {
self.data.clear();
}
pub fn keys(&self) -> Vec<&str> {
self.data.keys().map(|s| s.as_str()).collect()
}
}
pub fn new_kv_store() -> KeyValueStore {
KeyValueStore::new()
}
pub fn kv_set(store: &mut KeyValueStore, key: &str, value: KvValue) {
store.set(key, value);
}
pub fn kv_get<'a>(store: &'a KeyValueStore, key: &str) -> Option<&'a KvValue> {
store.get(key)
}
pub fn kv_delete(store: &mut KeyValueStore, key: &str) -> bool {
store.delete(key)
}
pub fn kv_len(store: &KeyValueStore) -> usize {
store.len()
}
pub fn kv_contains(store: &KeyValueStore, key: &str) -> bool {
store.contains(key)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_set_and_get_int() {
let mut s = new_kv_store();
kv_set(&mut s, "count", KvValue::Int(42));
assert_eq!(kv_get(&s, "count"), Some(&KvValue::Int(42)) );
}
#[test]
fn test_set_and_get_text() {
let mut s = new_kv_store();
kv_set(&mut s, "name", KvValue::Text("alice".into()));
assert_eq!(kv_get(&s, "name"), Some(&KvValue::Text("alice".into())) );
}
#[test]
fn test_delete() {
let mut s = new_kv_store();
kv_set(&mut s, "k", KvValue::Bool(true));
assert!(kv_delete(&mut s, "k") );
assert!(!kv_contains(&s, "k"));
}
#[test]
fn test_delete_missing() {
let mut s = new_kv_store();
assert!(!kv_delete(&mut s, "ghost") );
}
#[test]
fn test_len() {
let mut s = new_kv_store();
kv_set(&mut s, "a", KvValue::Int(1));
kv_set(&mut s, "b", KvValue::Int(2));
assert_eq!(kv_len(&s), 2 );
}
#[test]
fn test_contains() {
let mut s = new_kv_store();
kv_set(&mut s, "x", KvValue::Float(1.5));
assert!(kv_contains(&s, "x") );
assert!(!kv_contains(&s, "y") );
}
#[test]
fn test_clear() {
let mut s = new_kv_store();
kv_set(&mut s, "a", KvValue::Int(1));
s.clear();
assert!(s.is_empty() );
}
#[test]
fn test_bytes_value() {
let mut s = new_kv_store();
kv_set(&mut s, "data", KvValue::Bytes(vec![0, 1, 2]));
assert_eq!(kv_get(&s, "data"), Some(&KvValue::Bytes(vec![0, 1, 2])) );
}
#[test]
fn test_overwrite() {
let mut s = new_kv_store();
kv_set(&mut s, "v", KvValue::Int(1));
kv_set(&mut s, "v", KvValue::Int(2));
assert_eq!(kv_get(&s, "v"), Some(&KvValue::Int(2)) );
assert_eq!(kv_len(&s), 1);
}
#[test]
fn test_keys() {
let mut s = new_kv_store();
kv_set(&mut s, "p", KvValue::Bool(false));
let keys = s.keys();
assert!(keys.contains(&"p") );
}
}