#![cfg(feature = "std")]
use std::collections::HashMap;
use osom_lib_alloc::{std_allocator::StdAllocator, traits::Allocator};
use osom_lib_try_clone::TryClone;
use crate::immutable::{ImmutableString, serde::StringCache};
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub struct StdStringCache<TAllocator: Allocator + TryClone> {
allocator: TAllocator,
cache: HashMap<ImmutableString<TAllocator>, ()>,
}
impl<TAllocator: Allocator + TryClone> StdStringCache<TAllocator> {
#[inline]
pub fn with_allocator(allocator: TAllocator) -> Self {
Self {
allocator,
cache: HashMap::new(),
}
}
}
impl StdStringCache<StdAllocator> {
#[inline(always)]
pub fn new() -> Self {
Self::with_allocator(StdAllocator::default())
}
}
impl<TAllocator: Allocator + TryClone> StringCache for StdStringCache<TAllocator> {
type TAllocator = TAllocator;
fn get_and_cache(&mut self, value: &str) -> Result<ImmutableString<Self::TAllocator>, super::CacheError> {
if let Some((imm, _)) = self.cache.get_key_value(value) {
let clone = imm.try_clone().map_err(|_| super::CacheError::new("Failed to clone ImmutableString"))?;
return Ok(clone);
}
let allocator_clone = self.allocator.try_clone().map_err(|_| super::CacheError::new("Failed to clone Allocator"))?;
let immutable_string = ImmutableString::from_str_slice_and_allocator(value, allocator_clone)
.map_err(|_| super::CacheError::new("Failed to create ImmutableString"))?;
self.cache.insert(immutable_string.clone(), ());
Ok(immutable_string)
}
}