fluent_fallback/env.rs
1//! Traits required to provide environment driven data for [`Localization`](crate::Localization).
2//!
3//! Since [`Localization`](crate::Localization) is a long-lived structure,
4//! the model in which the user provides ability for the system to react to changes
5//! is by implementing the given environmental trait and triggering
6//! [`Localization::on_change`](crate::Localization::on_change) method.
7//!
8//! At the moment just a single trait is provided, which allows the
9//! environment to feed a selection of locales to be provided to the instance.
10//!
11//! The locales provided to [`Localization`](crate::Localization) should be
12//! already negotiated to ensure that the resources in those locales
13//! are available. The list should also be sorted according to the user
14//! preference, as the order is significant for how [`Localization`](crate::Localization) performs
15//! fallbacking.
16use unic_langid::LanguageIdentifier;
17
18/// A trait used to provide a selection of locales to be used by the
19/// [`Localization`](crate::Localization) instance for runtime
20/// locale fallbacking.
21///
22/// # Example
23/// ```
24/// use fluent_fallback::{Localization, env::LocalesProvider};
25/// use fluent_resmgr::ResourceManager;
26/// use unic_langid::LanguageIdentifier;
27/// use std::{
28/// rc::Rc,
29/// cell::RefCell
30/// };
31///
32/// #[derive(Clone)]
33/// struct Env {
34/// locales: Rc<RefCell<Vec<LanguageIdentifier>>>,
35/// }
36///
37/// impl Env {
38/// pub fn new(locales: Vec<LanguageIdentifier>) -> Self {
39/// Self { locales: Rc::new(RefCell::new(locales)) }
40/// }
41///
42/// pub fn set_locales(&mut self, new_locales: Vec<LanguageIdentifier>) {
43/// let mut locales = self.locales.borrow_mut();
44/// locales.clear();
45/// locales.extend(new_locales);
46/// }
47/// }
48///
49/// impl LocalesProvider for Env {
50/// type Iter = <Vec<LanguageIdentifier> as IntoIterator>::IntoIter;
51/// fn locales(&self) -> Self::Iter {
52/// self.locales.borrow().clone().into_iter()
53/// }
54/// }
55///
56/// let res_mgr = ResourceManager::new("./path/{locale}/".to_string());
57///
58/// let mut env = Env::new(vec![
59/// "en-GB".parse().unwrap()
60/// ]);
61///
62/// let mut loc = Localization::with_env(vec![], true, env.clone(), res_mgr);
63///
64/// env.set_locales(vec![
65/// "de".parse().unwrap(),
66/// "en-GB".parse().unwrap(),
67/// ]);
68///
69/// loc.on_change();
70///
71/// // The next format call will attempt to localize to `de` first and
72/// // fallback on `en-GB`.
73/// ```
74pub trait LocalesProvider {
75 type Iter: Iterator<Item = LanguageIdentifier>;
76 fn locales(&self) -> Self::Iter;
77}
78
79impl LocalesProvider for Vec<LanguageIdentifier> {
80 type Iter = <Vec<LanguageIdentifier> as IntoIterator>::IntoIter;
81 fn locales(&self) -> Self::Iter {
82 self.clone().into_iter()
83 }
84}