Skip to main content

osom_lib_strings/immutable/serde/
std_string_cache.rs

1#![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/// The default string cache backed by the standard [`HashSet`].
11/// 
12/// Note: this struct is not `repr(C)`.
13#[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    /// Creates a new [`StdStringCache`] with the given allocator.
22    #[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    /// Creates a new [`StdStringCache`] with the default [`StdAllocator`].
33    #[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}