1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
use std::borrow::Borrow; use std::borrow::Cow; use fluent_bundle::FluentResource; use fluent_bundle::{FluentArgs, FluentBundle}; use reiterate::Reiterate; struct FluentBundleIterator<'loc, R> { iter: Box<dyn Iterator<Item = FluentBundle<R>> + 'loc>, } impl<'loc, R> Iterator for FluentBundleIterator<'loc, R> { type Item = Box<FluentBundle<R>>; fn next(&mut self) -> Option<Self::Item> { self.iter.next().map(Box::new) } } pub struct Localization<'loc, R> { pub resource_ids: Vec<String>, bundles: Reiterate<FluentBundleIterator<'loc, R>>, generate_bundles: Box<dyn FnMut(&[String]) -> FluentBundleIterator<'loc, R> + 'loc>, } impl<'loc, R> Localization<'loc, R> { pub fn new<F, I>(resource_ids: Vec<String>, mut generate_bundles: F) -> Self where F: FnMut(&[String]) -> I + 'loc, I: Iterator<Item = FluentBundle<R>> + 'loc, { let mut generate2 = move |x: &[String]| FluentBundleIterator { iter: Box::new(generate_bundles(x)), }; let bundles = Reiterate::new(generate2(&resource_ids)); Localization { resource_ids, bundles, generate_bundles: Box::new(generate2), } } pub fn on_change(&mut self) { self.bundles = Reiterate::new((self.generate_bundles)(&self.resource_ids)); } pub fn format_value<'l>(&'l mut self, id: &'l str, args: Option<&'l FluentArgs>) -> Cow<'l, str> where R: Borrow<FluentResource>, { for bundle in &self.bundles { if let Some(msg) = bundle.get_message(id) { if let Some(pattern) = msg.value { let mut errors = vec![]; return bundle.format_pattern(pattern, args, &mut errors); } } } id.into() } }