10
10
//!
11
11
//! * [`FluentMessage`] - A single translation unit
12
12
//! * [`FluentResource`] - A list of [`FluentMessage`] units
13
- //! * [`FluentBundle`] - A collection of [`FluentResource`] lists
14
- //! * [`FluentArgs`] - A list of [`FluentValue`] elements used to resolve a [`FluentMessage`] value
15
- //!
16
- //! # 1) Message
17
- //!
18
- //! [`FluentMessage`] is the core unit of the system.
19
- //! It has an identifier, a value and a list of attributes.
20
- //!
21
- //! The identifier is a key that must be unique within a [`FluentResource`] to
22
- //! which the message belongs to.
23
- //!
24
- //! The shape of the message must also contain a value, attributes or both.
25
- //!
26
- //! ### Simple Message
27
- //!
28
- //! ```text
29
- //! hello-world = Hello, { $user }!
30
- //! ```
31
- //!
32
- //! ### Compound Message
33
- //!
34
- //! ```text
35
- //! confirm-modal = Are you sure?
36
- //! .confirm = Yes
37
- //! .cancel = No
38
- //! .tooltip = Closing the window will lose all unsaved data.
39
- //! ```
40
- //!
41
- //! # 2) Resource
42
- //!
43
- //! [`FluentResource`] wraps an [`Abstract Syntax Tree`](../fluent_syntax/ast/index.html) produced by the
44
- //! [`parser`](../fluent_syntax/parser/index.html) and provides an access to a list
45
- //! of its entries.
46
- //!
47
- //! A good mental model for a resource is a single FTL file, but in the future
48
- //! there's nothing preventing a resource from being stored in a data base,
49
- //! pre-parsed format or in some other structured form.
13
+ //! * [`FluentBundle`](crate::bundle::FluentBundle) - A collection of [`FluentResource`] lists
14
+ //! * [`FluentArgs`] - A list of elements used to resolve a [`FluentMessage`] value
50
15
//!
51
16
//! # 3) Bundle
52
17
//!
69
34
//! # 4) Arguments & Values
70
35
//!
71
36
//! [`FluentArgs`] is a collection, similar to a `HashMap`, which stores a key-value pair list of
72
- //! arguments provided by the developer to the [`format_pattern`](FluentBundle::format_pattern) method.
37
+ //! arguments provided by the developer to the [`format_pattern`](crate::bundle:: FluentBundle::format_pattern) method.
73
38
//! Those arguments are used during message formatting to resolve selections, or can be
74
39
//! interpolated into the message as a variable.
75
40
//!
153
118
//! [`FluentValue`]: ./types/enum.FluentValue.html
154
119
//! [`FluentArgs`]: ./struct.FluentArgs.html
155
120
mod args;
156
- mod bundle;
157
- pub mod concurrent;
121
+ pub mod bundle;
122
+ mod concurrent;
158
123
mod entry;
159
124
mod errors;
160
125
pub mod memoizer;
@@ -164,105 +129,14 @@ mod resource;
164
129
pub mod types;
165
130
166
131
pub use args:: FluentArgs ;
167
- use bundle:: FluentBundle as FluentBundleBase ;
168
-
169
- /// A collection of localization messages for a single locale, which are meant
170
- /// to be used together in a single view, widget or any other UI abstraction.
171
- ///
172
- /// # Examples
173
- ///
174
- /// ```
175
- /// use fluent_bundle::{FluentBundle, FluentResource, FluentValue, FluentArgs};
176
- /// use unic_langid::langid;
177
- ///
178
- /// let ftl_string = String::from("intro = Welcome, { $name }.");
179
- /// let resource = FluentResource::try_new(ftl_string)
180
- /// .expect("Could not parse an FTL string.");
181
- ///
182
- /// let langid_en = langid!("en-US");
183
- /// let mut bundle = FluentBundle::new(vec![langid_en]);
184
- ///
185
- /// bundle.add_resource(&resource)
186
- /// .expect("Failed to add FTL resources to the bundle.");
187
- ///
188
- /// let mut args = FluentArgs::new();
189
- /// args.set("name", FluentValue::from("Rustacean"));
190
- ///
191
- /// let msg = bundle.get_message("intro").expect("Message doesn't exist.");
192
- /// let mut errors = vec![];
193
- /// let pattern = msg.value().expect("Message has no value.");
194
- /// let value = bundle.format_pattern(&pattern, Some(&args), &mut errors);
195
- /// assert_eq!(&value, "Welcome, \u{2068}Rustacean\u{2069}.");
196
- ///
197
- /// ```
198
- ///
199
- /// # `FluentBundle` Life Cycle
200
- ///
201
- /// ## Create a bundle
202
- ///
203
- /// To create a bundle, call [`FluentBundle::new`] with a locale list that represents the best
204
- /// possible fallback chain for a given locale. The simplest case is a one-locale list.
205
- ///
206
- /// Fluent uses [`LanguageIdentifier`] which can be created using `langid!` macro.
207
- ///
208
- /// ## Add Resources
209
- ///
210
- /// Next, call [`add_resource`] one or more times, supplying translations in the FTL syntax.
211
- ///
212
- /// Since [`FluentBundle`] is generic over anything that can borrow a [`FluentResource`],
213
- /// one can use [`FluentBundle`] to own its resources, store references to them,
214
- /// or even [`Rc<FluentResource>`] or [`Arc<FluentResource>`].
215
- ///
216
- /// The [`FluentBundle`] instance is now ready to be used for localization.
217
- ///
218
- /// ## Format
219
- ///
220
- /// To format a translation, call [`get_message`] to retrieve a [`FluentMessage`],
221
- /// and then call [`format_pattern`] on the message value or attribute in order to
222
- /// retrieve the translated string.
223
- ///
224
- /// The result of [`format_pattern`] is an [`Cow<str>`]. It is
225
- /// recommended to treat the result as opaque from the perspective of the program and use it only
226
- /// to display localized messages. Do not examine it or alter in any way before displaying. This
227
- /// is a general good practice as far as all internationalization operations are concerned.
228
- ///
229
- /// If errors were encountered during formatting, they will be
230
- /// accumulated in the [`Vec<FluentError>`] passed as the third argument.
231
- ///
232
- /// While they are not fatal, they usually indicate problems with the translation,
233
- /// and should be logged or reported in a way that allows the developer to notice
234
- /// and fix them.
235
- ///
236
- ///
237
- /// # Locale Fallback Chain
238
- ///
239
- /// [`FluentBundle`] stores messages in a single locale, but keeps a locale fallback chain for the
240
- /// purpose of language negotiation with i18n formatters. For instance, if date and time formatting
241
- /// are not available in the first locale, [`FluentBundle`] will use its `locales` fallback chain
242
- /// to negotiate a sensible fallback for date and time formatting.
243
- ///
244
- /// # Concurrency
132
+ /// Specialized [`FluentBundle`](crate::bundle::FluentBundle) over
133
+ /// non-concurrent [`IntlLangMemoizer`](intl_memoizer::IntlLangMemoizer).
245
134
///
246
- /// As you may have noticed, `FluentBundle` is a specialization of [`FluentBundle`]
247
- /// which works with an [`IntlMemoizer`][] over `RefCell`.
248
- /// In scenarios where the memoizer must work concurrently, there's an implementation of
249
- /// `IntlMemoizer` that uses `Mutex` and there's [`concurrent::FluentBundle`] which works with that.
135
+ /// This is the basic variant of the [`FluentBundle`](crate::bundle::FluentBundle).
250
136
///
251
- /// [`add_resource`]: ./bundle/struct.FluentBundle.html#method.add_resource
252
- /// [`FluentBundle::new`]: ./bundle/struct.FluentBundle.html#method.new
253
- /// [`FluentMessage`]: ./struct.FluentMessage.html
254
- /// [`FluentBundle`]: ./type.FluentBundle.html
255
- /// [`FluentResource`]: ./struct.FluentResource.html
256
- /// [`get_message`]: ./bundle/struct.FluentBundle.html#method.get_message
257
- /// [`format_pattern`]: ./bundle/struct.FluentBundle.html#method.format_pattern
258
- /// [`Cow<str>`]: http://doc.rust-lang.org/std/borrow/enum.Cow.html
259
- /// [`Rc<FluentResource>`]: https://doc.rust-lang.org/std/rc/struct.Rc.html
260
- /// [`Arc<FluentResource>`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
261
- /// [`LanguageIdentifier`]: https://crates.io/crates/unic-langid
262
- /// [`IntlMemoizer`]: https://github.com/projectfluent/fluent-rs/tree/master/intl-memoizer
263
- /// [`Vec<FluentError>`]: ./enum.FluentError.html
264
- /// [`concurrent::FluentBundle`]: ./concurrent/type.FluentBundle.html
265
- pub type FluentBundle < R > = FluentBundleBase < R , intl_memoizer:: IntlLangMemoizer > ;
137
+ /// The concurrent specialization, can be constructed with
138
+ /// [`FluentBundle::new_concurrent`](crate::bundle::FluentBundle::new_concurrent).
139
+ pub type FluentBundle < R > = bundle:: FluentBundle < R , intl_memoizer:: IntlLangMemoizer > ;
266
140
pub use errors:: FluentError ;
267
141
pub use message:: { FluentAttribute , FluentMessage } ;
268
142
pub use resource:: FluentResource ;
0 commit comments