osom_lib_strings/immutable/serde/
std_string_cache.rs1#![cfg(feature = "std")]
2#![allow(clippy::default_constructed_unit_structs)]
3use std::collections::HashSet;
4
5use osom_lib_alloc::{std_allocator::StdAllocator, traits::Allocator};
6use osom_lib_try_clone::TryClone;
7
8use crate::immutable::{ImmutableString, serde::StringCache};
9
10#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
14#[must_use]
15pub struct StdStringCache<TAllocator: Allocator + TryClone> {
16 allocator: TAllocator,
17 cache: HashSet<ImmutableString<TAllocator>>,
18}
19
20impl<TAllocator: Allocator + TryClone> StdStringCache<TAllocator> {
21 #[inline]
23 pub fn with_allocator(allocator: TAllocator) -> Self {
24 Self {
25 allocator,
26 cache: HashSet::new(),
27 }
28 }
29}
30
31impl StdStringCache<StdAllocator> {
32 #[inline(always)]
34 pub fn new() -> Self {
35 Self::with_allocator(StdAllocator::default())
36 }
37}
38
39impl Default for StdStringCache<StdAllocator> {
40 fn default() -> Self {
41 Self::new()
42 }
43}
44
45impl<TAllocator: Allocator + TryClone> StringCache for StdStringCache<TAllocator> {
46 type TAllocator = TAllocator;
47
48 fn get_and_cache(&mut self, value: &str) -> Result<ImmutableString<Self::TAllocator>, super::CacheError> {
49 if let Some(imm) = self.cache.get(value) {
50 let clone = imm.try_clone().map_err(|_| super::CacheError::new("Failed to clone ImmutableString"))?;
51 return Ok(clone);
52 }
53
54 let allocator_clone = self.allocator.try_clone().map_err(|_| super::CacheError::new("Failed to clone Allocator"))?;
55 let immutable_string = ImmutableString::from_str_slice_and_allocator(value, allocator_clone)
56 .map_err(|_| super::CacheError::new("Failed to create ImmutableString"))?;
57 self.cache.insert(immutable_string.clone());
58 Ok(immutable_string)
59 }
60}