Skip to content

Commit c34b16d

Browse files
add DataProvider argument to Memoizable
1 parent 860b1f0 commit c34b16d

File tree

11 files changed

+121
-33
lines changed

11 files changed

+121
-33
lines changed

fluent-bundle/examples/custom_type.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl FluentType for DateTime {
107107
}
108108
fn as_string(&self, intls: &intl_memoizer::IntlLangMemoizer) -> std::borrow::Cow<'static, str> {
109109
intls
110-
.with_try_get::<DateTimeFormatter, _, _>((self.options.clone(),), |dtf| {
110+
.with_try_get::<DateTimeFormatter, _, _>((self.options.clone(),), &(), |dtf| {
111111
dtf.format(self.epoch).into()
112112
})
113113
.expect("Failed to format a date.")
@@ -143,7 +143,13 @@ impl DateTimeFormatter {
143143
impl Memoizable for DateTimeFormatter {
144144
type Args = (DateTimeOptions,);
145145
type Error = ();
146-
fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result<Self, Self::Error> {
146+
type DataProvider = ();
147+
148+
fn construct(
149+
lang: LanguageIdentifier,
150+
args: Self::Args,
151+
_: &Self::DataProvider,
152+
) -> Result<Self, Self::Error> {
147153
Self::new(lang, args.0)
148154
}
149155
}

fluent-bundle/src/bundle.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -598,14 +598,19 @@ impl crate::memoizer::MemoizerKind for IntlLangMemoizer {
598598
Self::new(lang)
599599
}
600600

601-
fn with_try_get_threadsafe<I, R, U>(&self, args: I::Args, cb: U) -> Result<R, I::Error>
601+
fn with_try_get_threadsafe<I, R, U>(
602+
&self,
603+
args: I::Args,
604+
data_provider: &I::DataProvider,
605+
cb: U,
606+
) -> Result<R, I::Error>
602607
where
603608
Self: Sized,
604609
I: intl_memoizer::Memoizable + Send + Sync + 'static,
605610
I::Args: Send + Sync + 'static,
606611
U: FnOnce(&I) -> R,
607612
{
608-
self.with_try_get(args, cb)
613+
self.with_try_get(args, data_provider, cb)
609614
}
610615

611616
fn stringify_value(

fluent-bundle/src/concurrent.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,19 @@ impl MemoizerKind for IntlLangMemoizer {
4343
Self::new(lang)
4444
}
4545

46-
fn with_try_get_threadsafe<I, R, U>(&self, args: I::Args, cb: U) -> Result<R, I::Error>
46+
fn with_try_get_threadsafe<I, R, U>(
47+
&self,
48+
args: I::Args,
49+
data_provider: &I::DataProvider,
50+
cb: U,
51+
) -> Result<R, I::Error>
4752
where
4853
Self: Sized,
4954
I: Memoizable + Send + Sync + 'static,
5055
I::Args: Send + Sync + 'static,
5156
U: FnOnce(&I) -> R,
5257
{
53-
self.with_try_get(args, cb)
58+
self.with_try_get(args, data_provider, cb)
5459
}
5560

5661
fn stringify_value(&self, value: &dyn FluentType) -> std::borrow::Cow<'static, str> {

fluent-bundle/src/memoizer.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@ pub trait MemoizerKind: 'static {
1818
///
1919
/// `U` - The callback that accepts the instance of the intl formatter, and generates
2020
/// some kind of results `R`.
21-
fn with_try_get_threadsafe<I, R, U>(&self, args: I::Args, callback: U) -> Result<R, I::Error>
21+
fn with_try_get_threadsafe<I, R, U>(
22+
&self,
23+
args: I::Args,
24+
data_provider: &I::DataProvider,
25+
callback: U,
26+
) -> Result<R, I::Error>
2227
where
2328
Self: Sized,
2429
I: Memoizable + Send + Sync + 'static,

fluent-bundle/src/resolvable.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use std::borrow::Cow;
2+
3+
use crate::FluentBundle;
4+
5+
pub trait Resolvable<R> {
6+
fn resolve(bundle: FluentBundle<R>);
7+
}
8+
9+
pub trait SimpleResolvable<R>: Resolvable<R> {
10+
const ID: &'static str;
11+
12+
fn resolve_simple(bundle: FluentBundle<R>) -> Result<Cow<str>> {
13+
let msg = bundle.get_message(Self::ID);
14+
if let Some(v) = msg.unwrap().value() {
15+
return Ok(Cow::Borrowed(v.))
16+
}
17+
}
18+
}
19+
20+
impl<R> SimpleResolvable<R> for () {}

fluent-bundle/src/types/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ impl<'source> FluentValue<'source> {
205205
.intls
206206
.with_try_get_threadsafe::<PluralRules, _, _>(
207207
(PluralRuleType::CARDINAL,),
208+
&(),
208209
|pr| pr.0.select(b) == Ok(cat),
209210
)
210211
.unwrap()
@@ -227,7 +228,7 @@ impl<'source> FluentValue<'source> {
227228
}
228229
match self {
229230
FluentValue::String(s) => w.write_str(s),
230-
FluentValue::Number(n) => w.write_str(&n.as_string()),
231+
FluentValue::Number(n) => w.write_str(&n.as_string(scope.bundle)),
231232
FluentValue::Custom(s) => w.write_str(&scope.bundle.intls.stringify_value(&**s)),
232233
FluentValue::Error => Ok(()),
233234
FluentValue::None => Ok(()),
@@ -246,7 +247,7 @@ impl<'source> FluentValue<'source> {
246247
}
247248
match self {
248249
FluentValue::String(s) => s.clone(),
249-
FluentValue::Number(n) => n.as_string(),
250+
FluentValue::Number(n) => n.as_string(scope.bundle),
250251
FluentValue::Custom(s) => scope.bundle.intls.stringify_value(&**s),
251252
FluentValue::Error => "".into(),
252253
FluentValue::None => "".into(),

fluent-bundle/src/types/plural.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ pub struct PluralRules(pub IntlPluralRules);
88
impl Memoizable for PluralRules {
99
type Args = (PluralRuleType,);
1010
type Error = &'static str;
11-
fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result<Self, Self::Error> {
11+
type DataProvider = ();
12+
13+
fn construct(
14+
lang: LanguageIdentifier,
15+
args: Self::Args,
16+
_: &Self::DataProvider,
17+
) -> Result<Self, Self::Error> {
1218
let default_lang: LanguageIdentifier = "en".parse().unwrap();
1319
let pr_lang = negotiate_languages(
1420
&[lang],

intl-memoizer/examples/numberformat.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,12 @@ impl NumberFormat {
2828
impl Memoizable for NumberFormat {
2929
type Args = (NumberFormatOptions,);
3030
type Error = ();
31-
fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result<Self, Self::Error> {
31+
type DataProvider = ();
32+
fn construct(
33+
lang: LanguageIdentifier,
34+
args: Self::Args,
35+
_: &Self::DataProvider,
36+
) -> Result<Self, Self::Error> {
3237
Self::new(lang, args.0)
3338
}
3439
}
@@ -45,7 +50,7 @@ fn main() {
4550
maximum_fraction_digits: 5,
4651
};
4752
let result = lang_memoizer
48-
.with_try_get::<NumberFormat, _, _>((options,), |nf| nf.format(2))
53+
.with_try_get::<NumberFormat, _, _>((options,), &(), |nf| nf.format(2))
4954
.unwrap();
5055

5156
assert_eq!(&result, "en-US: 2, MFD: 3");
@@ -57,7 +62,7 @@ fn main() {
5762
maximum_fraction_digits: 5,
5863
};
5964
let result = lang_memoizer
60-
.with_try_get::<NumberFormat, _, _>((options,), |nf| nf.format(1))
65+
.with_try_get::<NumberFormat, _, _>((options,), &(), |nf| nf.format(1))
6166
.unwrap();
6267
assert_eq!(&result, "en-US: 1, MFD: 3");
6368
}
@@ -70,7 +75,7 @@ fn main() {
7075
maximum_fraction_digits: 5,
7176
};
7277
let result = lang_memoizer
73-
.with_try_get::<NumberFormat, _, _>((options,), |nf| nf.format(7))
78+
.with_try_get::<NumberFormat, _, _>((options,), &(), |nf| nf.format(7))
7479
.unwrap();
7580

7681
assert_eq!(&result, "en-US: 7, MFD: 3");

intl-memoizer/examples/pluralrules.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ impl PluralRules {
1313
impl Memoizable for PluralRules {
1414
type Args = (PluralRuleType,);
1515
type Error = &'static str;
16-
fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result<Self, Self::Error> {
16+
type DataProvider = ();
17+
fn construct(
18+
lang: LanguageIdentifier,
19+
args: Self::Args,
20+
_: &Self::DataProvider,
21+
) -> Result<Self, Self::Error> {
1722
Self::new(lang, args.0)
1823
}
1924
}
@@ -24,7 +29,7 @@ fn main() {
2429
let lang: LanguageIdentifier = "en".parse().unwrap();
2530
let lang_memoizer = memoizer.get_for_lang(lang);
2631
let result = lang_memoizer
27-
.with_try_get::<PluralRules, _, _>((PluralRuleType::CARDINAL,), |pr| pr.0.select(5))
32+
.with_try_get::<PluralRules, _, _>((PluralRuleType::CARDINAL,), &(), |pr| pr.0.select(5))
2833
.unwrap();
2934

3035
assert_eq!(result, Ok(PluralCategory::OTHER));

intl-memoizer/src/concurrent.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ impl IntlLangMemoizer {
2222
/// Lazily initialize and run a formatter. See
2323
/// [`intl_memoizer::IntlLangMemoizer::with_try_get`](../struct.IntlLangMemoizer.html#method.with_try_get)
2424
/// for documentation.
25-
pub fn with_try_get<I, R, U>(&self, args: I::Args, cb: U) -> Result<R, I::Error>
25+
pub fn with_try_get<I, R, U>(
26+
&self,
27+
args: I::Args,
28+
data_provider: &I::DataProvider,
29+
cb: U,
30+
) -> Result<R, I::Error>
2631
where
2732
Self: Sized,
2833
I: Memoizable + Sync + Send + 'static,
@@ -37,7 +42,7 @@ impl IntlLangMemoizer {
3742
let e = match cache.entry(args.clone()) {
3843
Entry::Occupied(entry) => entry.into_mut(),
3944
Entry::Vacant(entry) => {
40-
let val = I::construct(self.lang.clone(), args)?;
45+
let val = I::construct(self.lang.clone(), args, data_provider)?;
4146
entry.insert(val)
4247
}
4348
};

intl-memoizer/src/lib.rs

+40-15
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,16 @@ pub trait Memoizable {
2222
/// Type of any errors that can occur during the construction process.
2323
type Error;
2424

25+
/// Type of shared data provider
26+
type DataProvider;
27+
2528
/// Construct a formatter. This maps the [`Self::Args`] type to the actual constructor
2629
/// for an intl formatter.
27-
fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result<Self, Self::Error>
30+
fn construct(
31+
lang: LanguageIdentifier,
32+
args: Self::Args,
33+
data_provider: &Self::DataProvider,
34+
) -> Result<Self, Self::Error>
2835
where
2936
Self: std::marker::Sized;
3037
}
@@ -92,9 +99,12 @@ pub trait Memoizable {
9299
/// /// If the construtor is fallible, than errors can be described here.
93100
/// type Error = ();
94101
///
102+
/// /// For accessing shared state to construct
103+
/// type DataProvider = ();
104+
///
95105
/// /// This function wires together the `Args` and `Error` type to construct
96106
/// /// the intl API. In our example, there is
97-
/// fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result<Self, Self::Error> {
107+
/// fn construct(lang: LanguageIdentifier, args: Self::Args, data_provider: &Self::DataProvider) -> Result<Self, Self::Error> {
98108
/// // Keep track for example purposes that this was constructed.
99109
/// increment_constructs();
100110
///
@@ -121,13 +131,13 @@ pub trait Memoizable {
121131
/// // more details.
122132
///
123133
/// let result1 = memoizer
124-
/// .with_try_get::<ExampleFormatter, _, _>(construct_args.clone(), |intl_example| {
134+
/// .with_try_get::<ExampleFormatter, _, _>(construct_args.clone(), &(), |intl_example| {
125135
/// intl_example.format(message1)
126136
/// });
127137
///
128138
/// // The memoized instance of `ExampleFormatter` will be re-used.
129139
/// let result2 = memoizer
130-
/// .with_try_get::<ExampleFormatter, _, _>(construct_args.clone(), |intl_example| {
140+
/// .with_try_get::<ExampleFormatter, _, _>(construct_args.clone(), &(), |intl_example| {
131141
/// intl_example.format(message2)
132142
/// });
133143
///
@@ -149,13 +159,13 @@ pub trait Memoizable {
149159
///
150160
/// // Since the constructor args changed, `ExampleFormatter` will be re-constructed.
151161
/// let result1 = memoizer
152-
/// .with_try_get::<ExampleFormatter, _, _>(construct_args.clone(), |intl_example| {
162+
/// .with_try_get::<ExampleFormatter, _, _>(construct_args.clone(), &(), |intl_example| {
153163
/// intl_example.format(message1)
154164
/// });
155165
///
156166
/// // The memoized instance of `ExampleFormatter` will be re-used.
157167
/// let result2 = memoizer
158-
/// .with_try_get::<ExampleFormatter, _, _>(construct_args.clone(), |intl_example| {
168+
/// .with_try_get::<ExampleFormatter, _, _>(construct_args.clone(), &(), |intl_example| {
159169
/// intl_example.format(message2)
160170
/// });
161171
///
@@ -205,7 +215,12 @@ impl IntlLangMemoizer {
205215
///
206216
/// U - The callback function. Takes an instance of `I` as the first parameter and
207217
/// returns the R value.
208-
pub fn with_try_get<I, R, U>(&self, construct_args: I::Args, callback: U) -> Result<R, I::Error>
218+
pub fn with_try_get<I, R, U>(
219+
&self,
220+
construct_args: I::Args,
221+
data_provider: &I::DataProvider,
222+
callback: U,
223+
) -> Result<R, I::Error>
209224
where
210225
Self: Sized,
211226
I: Memoizable + 'static,
@@ -222,7 +237,7 @@ impl IntlLangMemoizer {
222237
let e = match cache.entry(construct_args.clone()) {
223238
Entry::Occupied(entry) => entry.into_mut(),
224239
Entry::Vacant(entry) => {
225-
let val = I::construct(self.lang.clone(), construct_args)?;
240+
let val = I::construct(self.lang.clone(), construct_args, data_provider)?;
226241
entry.insert(val)
227242
}
228243
};
@@ -269,7 +284,8 @@ impl IntlLangMemoizer {
269284
/// # impl Memoizable for ExampleFormatter {
270285
/// # type Args = (String,);
271286
/// # type Error = ();
272-
/// # fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result<Self, Self::Error> {
287+
/// # type DataProvider = ();
288+
/// # fn construct(lang: LanguageIdentifier, args: Self::Args, data_provider: &Self::DataProvider) -> Result<Self, Self::Error> {
273289
/// # Ok(Self {
274290
/// # lang,
275291
/// # prefix: args.0,
@@ -295,7 +311,7 @@ impl IntlLangMemoizer {
295311
/// //
296312
/// // See `IntlLangMemoizer` for more details on this step.
297313
/// let en_us_result = en_us_memoizer
298-
/// .with_try_get::<ExampleFormatter, _, _>(construct_args.clone(), |intl_example| {
314+
/// .with_try_get::<ExampleFormatter, _, _>(construct_args.clone(), &(), |intl_example| {
299315
/// intl_example.format(message)
300316
/// });
301317
///
@@ -312,7 +328,7 @@ impl IntlLangMemoizer {
312328
/// let de_de_memoizer: Rc<IntlLangMemoizer> = memoizer.get_for_lang(de_de);
313329
///
314330
/// let de_de_result = de_de_memoizer
315-
/// .with_try_get::<ExampleFormatter, _, _>(construct_args.clone(), |intl_example| {
331+
/// .with_try_get::<ExampleFormatter, _, _>(construct_args.clone(), &(), |intl_example| {
316332
/// intl_example.format(message)
317333
/// });
318334
///
@@ -380,7 +396,12 @@ mod tests {
380396
impl Memoizable for PluralRules {
381397
type Args = (PluralRuleType,);
382398
type Error = &'static str;
383-
fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result<Self, Self::Error> {
399+
type DataProvider = ();
400+
fn construct(
401+
lang: LanguageIdentifier,
402+
args: Self::Args,
403+
_: &Self::DataProvider,
404+
) -> Result<Self, Self::Error> {
384405
Self::new(lang, args.0)
385406
}
386407
}
@@ -394,7 +415,9 @@ mod tests {
394415
let en_memoizer = memoizer.get_for_lang(lang.clone());
395416

396417
let result = en_memoizer
397-
.with_try_get::<PluralRules, _, _>((PluralRuleType::CARDINAL,), |cb| cb.0.select(5))
418+
.with_try_get::<PluralRules, _, _>((PluralRuleType::CARDINAL,), &(), |cb| {
419+
cb.0.select(5)
420+
})
398421
.unwrap();
399422
assert_eq!(result, Ok(PluralCategory::OTHER));
400423
}
@@ -403,7 +426,9 @@ mod tests {
403426
let en_memoizer = memoizer.get_for_lang(lang);
404427

405428
let result = en_memoizer
406-
.with_try_get::<PluralRules, _, _>((PluralRuleType::CARDINAL,), |cb| cb.0.select(5))
429+
.with_try_get::<PluralRules, _, _>((PluralRuleType::CARDINAL,), &(), |cb| {
430+
cb.0.select(5)
431+
})
407432
.unwrap();
408433
assert_eq!(result, Ok(PluralCategory::OTHER));
409434
}
@@ -420,7 +445,7 @@ mod tests {
420445
let memoizer = Arc::clone(&memoizer);
421446
threads.push(thread::spawn(move || {
422447
memoizer
423-
.with_try_get::<PluralRules, _, _>((PluralRuleType::CARDINAL,), |cb| {
448+
.with_try_get::<PluralRules, _, _>((PluralRuleType::CARDINAL,), &(), |cb| {
424449
cb.0.select(5)
425450
})
426451
.expect("Failed to get a PluralRules result.")

0 commit comments

Comments
 (0)