use crate::common::{AttributeAware, Key, Value};
use crate::errors::NitriteResult;
use crate::store::iters::{
EntryIterator, KeyIterator, ValueIterator,
};
use crate::store::NitriteStore;
use std::fmt::Debug;
use std::iter::Rev;
use std::ops::Deref;
use std::sync::Arc;
pub trait NitriteMapProvider: AttributeAware + Send + Sync {
fn contains_key(&self, key: &Key) -> NitriteResult<bool>;
fn get(&self, key: &Key) -> NitriteResult<Option<Value>>;
fn clear(&self) -> NitriteResult<()>;
fn is_closed(&self) -> NitriteResult<bool>;
fn close(&self) -> NitriteResult<()>;
fn values(&self) -> NitriteResult<ValueIterator>;
fn keys(&self) -> NitriteResult<KeyIterator>;
fn remove(&self, key: &Key) -> NitriteResult<Option<Value>>;
fn put(&self, key: Key, value: Value) -> NitriteResult<()>;
fn put_all(&self, entries: Vec<(Key, Value)>) -> NitriteResult<()> {
for (key, value) in entries {
self.put(key, value)?;
}
Ok(())
}
fn size(&self) -> NitriteResult<u64>;
fn put_if_absent(&self, key: Key, value: Value) -> NitriteResult<Option<Value>>;
fn first_key(&self) -> NitriteResult<Option<Key>>;
fn last_key(&self) -> NitriteResult<Option<Key>>;
fn higher_key(&self, key: &Key) -> NitriteResult<Option<Key>>;
fn ceiling_key(&self, key: &Key) -> NitriteResult<Option<Key>>;
fn lower_key(&self, key: &Key) -> NitriteResult<Option<Key>>;
fn floor_key(&self, key: &Key) -> NitriteResult<Option<Key>>;
fn is_empty(&self) -> NitriteResult<bool>;
fn get_store(&self) -> NitriteResult<NitriteStore>;
fn get_name(&self) -> NitriteResult<String>;
fn entries(&self) -> NitriteResult<EntryIterator>;
fn reverse_entries(&self) -> NitriteResult<Rev<EntryIterator>>;
fn dispose(&self) -> NitriteResult<()>;
fn is_dropped(&self) -> NitriteResult<bool>;
}
#[derive(Clone)]
pub struct NitriteMap {
inner: Arc<dyn NitriteMapProvider>,
}
impl Deref for NitriteMap {
type Target = Arc<dyn NitriteMapProvider>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl NitriteMap {
pub fn new<T: NitriteMapProvider + 'static>(inner: T) -> Self {
NitriteMap { inner: Arc::new(inner) }
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::common::{Attributes, Key, Value};
use crate::errors::NitriteError;
use crate::store::iters::{EntryIterator, KeyIterator, ValueIterator};
use crate::store::NitriteStore;
#[derive(Copy, Clone)]
struct MockNitriteMap;
impl AttributeAware for MockNitriteMap {
fn attributes(&self) -> NitriteResult<Option<Attributes>> {
Ok(None)
}
fn set_attributes(&self, _attributes: Attributes) -> NitriteResult<()> {
Ok(())
}
}
impl NitriteMapProvider for MockNitriteMap {
fn contains_key(&self, key: &Key) -> NitriteResult<bool> {
Ok(key == &Key::from("key1"))
}
fn get(&self, key: &Key) -> NitriteResult<Option<Value>> {
if key == &Key::from("key1") {
Ok(Some(Value::from("value1")))
} else {
Ok(None)
}
}
fn clear(&self) -> NitriteResult<()> {
Ok(())
}
fn is_closed(&self) -> NitriteResult<bool> {
Ok(false)
}
fn close(&self) -> NitriteResult<()> {
Ok(())
}
fn values(&self) -> NitriteResult<ValueIterator> {
Err(NitriteError::new("Invalid operation", crate::errors::ErrorKind::InvalidOperation))
}
fn keys(&self) -> NitriteResult<KeyIterator> {
Err(NitriteError::new("Invalid operation", crate::errors::ErrorKind::InvalidOperation))
}
fn remove(&self, key: &Key) -> NitriteResult<Option<Value>> {
if key == &Key::from("key1") {
Ok(Some(Value::from("value1")))
} else {
Ok(None)
}
}
fn put(&self, _key: Key, _value: Value) -> NitriteResult<()> {
Ok(())
}
fn size(&self) -> NitriteResult<u64> {
Ok(1)
}
fn put_if_absent(&self, key: Key, _value: Value) -> NitriteResult<Option<Value>> {
if key == Key::from("key1") {
Ok(Some(Value::from("value1")))
} else {
Ok(None)
}
}
fn first_key(&self) -> NitriteResult<Option<Key>> {
Ok(Some(Key::from("key1")))
}
fn last_key(&self) -> NitriteResult<Option<Key>> {
Ok(Some(Key::from("key1")))
}
fn higher_key(&self, _key: &Key) -> NitriteResult<Option<Key>> {
Ok(None)
}
fn ceiling_key(&self, key: &Key) -> NitriteResult<Option<Key>> {
Ok(Some(key.clone()))
}
fn lower_key(&self, _key: &Key) -> NitriteResult<Option<Key>> {
Ok(None)
}
fn floor_key(&self, key: &Key) -> NitriteResult<Option<Key>> {
Ok(Some(key.clone()))
}
fn is_empty(&self) -> NitriteResult<bool> {
Ok(false)
}
fn get_store(&self) -> NitriteResult<NitriteStore> {
Err(NitriteError::new("Invalid operation", crate::errors::ErrorKind::InvalidOperation))
}
fn get_name(&self) -> NitriteResult<String> {
Ok("test_map".to_string())
}
fn entries(&self) -> NitriteResult<EntryIterator> {
Err(NitriteError::new("Invalid operation", crate::errors::ErrorKind::InvalidOperation))
}
fn reverse_entries(&self) -> NitriteResult<Rev<EntryIterator>> {
Err(NitriteError::new("Invalid operation", crate::errors::ErrorKind::InvalidOperation))
}
fn dispose(&self) -> NitriteResult<()> {
Ok(())
}
fn is_dropped(&self) -> NitriteResult<bool> {
Ok(false)
}
}
#[test]
fn test_contains_key() {
let map = NitriteMap::new(MockNitriteMap);
assert!(map.contains_key(&Key::from("key1")).unwrap());
assert!(!map.contains_key(&Key::from("key2")).unwrap());
}
#[test]
fn test_get() {
let map = NitriteMap::new(MockNitriteMap);
assert_eq!(map.get(&Key::from("key1")).unwrap(), Some(Value::from("value1")));
assert_eq!(map.get(&Key::from("key2")).unwrap(), None);
}
#[test]
fn test_clear() {
let map = NitriteMap::new(MockNitriteMap);
assert!(map.clear().is_ok());
}
#[test]
fn test_is_closed() {
let map = NitriteMap::new(MockNitriteMap);
assert!(!map.is_closed().unwrap());
}
#[test]
fn test_close() {
let map = NitriteMap::new(MockNitriteMap);
assert!(map.close().is_ok());
}
#[test]
fn test_values() {
let map = NitriteMap::new(MockNitriteMap);
assert!(map.values().is_err());
}
#[test]
fn test_keys() {
let map = NitriteMap::new(MockNitriteMap);
assert!(map.keys().is_err());
}
#[test]
fn test_remove() {
let map = NitriteMap::new(MockNitriteMap);
assert_eq!(map.remove(&Key::from("key1")).unwrap(), Some(Value::from("value1")));
assert_eq!(map.remove(&Key::from("key2")).unwrap(), None);
}
#[test]
fn test_put() {
let map = NitriteMap::new(MockNitriteMap);
assert!(map.put(Key::from("key1"), Value::from("value1")).is_ok());
}
#[test]
fn test_size() {
let map = NitriteMap::new(MockNitriteMap);
assert_eq!(map.size().unwrap(), 1);
}
#[test]
fn test_put_if_absent() {
let map = NitriteMap::new(MockNitriteMap);
assert_eq!(map.put_if_absent(Key::from("key1"), Value::from("value1")).unwrap(), Some(Value::from("value1")));
assert_eq!(map.put_if_absent(Key::from("key2"), Value::from("value2")).unwrap(), None);
}
#[test]
fn test_first_key() {
let map = NitriteMap::new(MockNitriteMap);
assert_eq!(map.first_key().unwrap(), Some(Key::from("key1")));
}
#[test]
fn test_last_key() {
let map = NitriteMap::new(MockNitriteMap);
assert_eq!(map.last_key().unwrap(), Some(Key::from("key1")));
}
#[test]
fn test_higher_key() {
let map = NitriteMap::new(MockNitriteMap);
assert_eq!(map.higher_key(&Key::from("key1")).unwrap(), None);
}
#[test]
fn test_ceiling_key() {
let map = NitriteMap::new(MockNitriteMap);
assert_eq!(map.ceiling_key(&Key::from("key1")).unwrap(), Some(Key::from("key1")));
}
#[test]
fn test_lower_key() {
let map = NitriteMap::new(MockNitriteMap);
assert_eq!(map.lower_key(&Key::from("key1")).unwrap(), None);
}
#[test]
fn test_floor_key() {
let map = NitriteMap::new(MockNitriteMap);
assert_eq!(map.floor_key(&Key::from("key1")).unwrap(), Some(Key::from("key1")));
}
#[test]
fn test_is_empty() {
let map = NitriteMap::new(MockNitriteMap);
assert!(!map.is_empty().unwrap());
}
#[test]
fn test_get_store() {
let map = NitriteMap::new(MockNitriteMap);
assert!(map.get_store().is_err());
}
#[test]
fn test_get_name() {
let map = NitriteMap::new(MockNitriteMap);
assert_eq!(map.get_name().unwrap(), "test_map");
}
#[test]
fn test_entries() {
let map = NitriteMap::new(MockNitriteMap);
assert!(map.entries().is_err());
}
#[test]
fn test_reverse_entries() {
let map = NitriteMap::new(MockNitriteMap);
assert!(map.reverse_entries().is_err());
}
#[test]
fn test_dispose_map() {
let map = NitriteMap::new(MockNitriteMap);
assert!(map.dispose().is_ok());
}
#[test]
fn test_is_dropped() {
let map = NitriteMap::new(MockNitriteMap);
assert!(!map.is_dropped().unwrap());
}
#[test]
fn test_arc_cloning_efficiency() {
let map1 = NitriteMap::new(MockNitriteMap);
let map2 = map1.clone();
assert_eq!(map1.get_name().unwrap(), map2.get_name().unwrap());
}
#[test]
fn test_deref_access_efficiency() {
let map = NitriteMap::new(MockNitriteMap);
let _deref_target = &*map;
assert!(!map.is_empty().unwrap());
}
#[test]
fn test_multiple_sequential_operations() {
let map = NitriteMap::new(MockNitriteMap);
assert_eq!(map.size().unwrap(), 1);
assert!(map.contains_key(&Key::from("key1")).unwrap());
assert_eq!(map.get(&Key::from("key1")).unwrap(), Some(Value::from("value1")));
assert!(!map.is_empty().unwrap());
}
#[test]
fn test_put_if_absent_consistency() {
let map = NitriteMap::new(MockNitriteMap);
let result1 = map.put_if_absent(Key::from("key1"), Value::from("new_value1")).unwrap();
assert_eq!(result1, Some(Value::from("value1")));
let result2 = map.put_if_absent(Key::from("key1"), Value::from("another_value")).unwrap();
assert_eq!(result2, Some(Value::from("value1")));
}
#[test]
fn test_key_operations_efficiency() {
let map = NitriteMap::new(MockNitriteMap);
assert_eq!(map.first_key().unwrap(), Some(Key::from("key1")));
assert_eq!(map.last_key().unwrap(), Some(Key::from("key1")));
assert_eq!(map.ceiling_key(&Key::from("key1")).unwrap(), Some(Key::from("key1")));
assert_eq!(map.floor_key(&Key::from("key1")).unwrap(), Some(Key::from("key1")));
}
}