fluent_fallback/
localization.rs1use crate::{
2 bundles::Bundles,
3 env::LocalesProvider,
4 generator::{BundleGenerator, BundleIterator, BundleStream},
5 types::ResourceId,
6};
7use once_cell::sync::OnceCell;
8use rustc_hash::FxHashSet;
9use std::rc::Rc;
10
11pub struct Localization<G, P>
12where
13 G: BundleGenerator<LocalesIter = P::Iter>,
14 P: LocalesProvider,
15{
16 bundles: OnceCell<Rc<Bundles<G>>>,
17 generator: G,
18 provider: P,
19 sync: bool,
20 res_ids: FxHashSet<ResourceId>,
21}
22
23impl<G, P> Localization<G, P>
24where
25 G: BundleGenerator<LocalesIter = P::Iter> + Default,
26 P: LocalesProvider + Default,
27{
28 pub fn new<I>(res_ids: I, sync: bool) -> Self
29 where
30 I: IntoIterator<Item = ResourceId>,
31 {
32 Self {
33 bundles: OnceCell::new(),
34 generator: G::default(),
35 provider: P::default(),
36 sync,
37 res_ids: FxHashSet::from_iter(res_ids),
38 }
39 }
40}
41
42impl<G, P> Localization<G, P>
43where
44 G: BundleGenerator<LocalesIter = P::Iter>,
45 P: LocalesProvider,
46{
47 pub fn with_env<I>(res_ids: I, sync: bool, provider: P, generator: G) -> Self
48 where
49 I: IntoIterator<Item = ResourceId>,
50 {
51 Self {
52 bundles: OnceCell::new(),
53 generator,
54 provider,
55 sync,
56 res_ids: FxHashSet::from_iter(res_ids),
57 }
58 }
59
60 pub fn is_sync(&self) -> bool {
61 self.sync
62 }
63
64 pub fn add_resource_id<T: Into<ResourceId>>(&mut self, res_id: T) {
65 self.res_ids.insert(res_id.into());
66 self.on_change();
67 }
68
69 pub fn add_resource_ids(&mut self, res_ids: Vec<ResourceId>) {
70 self.res_ids.extend(res_ids);
71 self.on_change();
72 }
73
74 pub fn remove_resource_id<T: PartialEq<ResourceId>>(&mut self, res_id: T) -> usize {
75 self.res_ids.retain(|x| !res_id.eq(x));
76 self.on_change();
77 self.res_ids.len()
78 }
79
80 pub fn remove_resource_ids(&mut self, res_ids: Vec<ResourceId>) -> usize {
81 self.res_ids.retain(|x| !res_ids.contains(x));
82 self.on_change();
83 self.res_ids.len()
84 }
85
86 pub fn set_async(&mut self) {
87 if self.sync {
88 self.sync = false;
89 self.on_change();
90 }
91 }
92
93 pub fn on_change(&mut self) {
94 self.bundles.take();
95 }
96}
97
98impl<G, P> Localization<G, P>
99where
100 G: BundleGenerator<LocalesIter = P::Iter>,
101 G::Iter: BundleIterator,
102 P: LocalesProvider,
103{
104 pub fn prefetch_sync(&mut self) {
105 let bundles = self.bundles();
106 bundles.prefetch_sync();
107 }
108}
109
110impl<G, P> Localization<G, P>
111where
112 G: BundleGenerator<LocalesIter = P::Iter>,
113 G::Stream: BundleStream,
114 P: LocalesProvider,
115{
116 pub async fn prefetch_async(&mut self) {
117 let bundles = self.bundles();
118 bundles.prefetch_async().await;
119 }
120}
121
122impl<G, P> Localization<G, P>
123where
124 G: BundleGenerator<LocalesIter = P::Iter>,
125 P: LocalesProvider,
126{
127 pub fn bundles(&self) -> &Rc<Bundles<G>> {
128 self.bundles.get_or_init(|| {
129 Rc::new(Bundles::new(
130 self.sync,
131 self.res_ids.clone(),
132 &self.generator,
133 &self.provider,
134 ))
135 })
136 }
137}