1 | use super::*; |
2 | use std::sync::Mutex; |
3 | |
4 | #[derive (Debug)] |
5 | pub struct IntlLangMemoizer { |
6 | lang: LanguageIdentifier, |
7 | map: Mutex<type_map::concurrent::TypeMap>, |
8 | } |
9 | |
10 | impl IntlLangMemoizer { |
11 | pub fn new(lang: LanguageIdentifier) -> Self { |
12 | Self { |
13 | lang, |
14 | map: Mutex::new(type_map::concurrent::TypeMap::new()), |
15 | } |
16 | } |
17 | |
18 | pub fn with_try_get<I, R, U>(&self, args: I::Args, cb: U) -> Result<R, I::Error> |
19 | where |
20 | Self: Sized, |
21 | I: Memoizable + Sync + Send + 'static, |
22 | I::Args: Send + Sync + 'static, |
23 | U: FnOnce(&I) -> R, |
24 | { |
25 | let mut map = self.map.lock().unwrap(); |
26 | let cache = map |
27 | .entry::<HashMap<I::Args, I>>() |
28 | .or_insert_with(HashMap::new); |
29 | |
30 | let e = match cache.entry(args.clone()) { |
31 | Entry::Occupied(entry) => entry.into_mut(), |
32 | Entry::Vacant(entry) => { |
33 | let val = I::construct(self.lang.clone(), args)?; |
34 | entry.insert(val) |
35 | } |
36 | }; |
37 | Ok(cb(&e)) |
38 | } |
39 | } |
40 | |