1 //! Fluent is a modern localization system designed to improve how software is translated.
3 //! The Rust implementation provides the low level components for syntax operations, like parser
4 //! and AST, and the core localization struct - [`FluentBundle`].
6 //! [`FluentBundle`] is the low level container for storing and formatting localization messages
7 //! in a single locale.
9 //! This crate provides also a number of structures needed for a localization API such as [`FluentResource`],
10 //! [`FluentMessage`], [`FluentArgs`], and [`FluentValue`].
12 //! Together, they allow implementations to build higher-level APIs that use [`FluentBundle`]
13 //! and add user friendly helpers, framework bindings, error fallbacking,
14 //! language negotiation between user requested languages and available resources,
15 //! and I/O for loading selected resources.
20 //! use fluent::{FluentBundle, FluentValue, FluentResource, FluentArgs};
22 //! // Used to provide a locale for the bundle.
23 //! use unic_langid::LanguageIdentifier;
25 //! let ftl_string = String::from("
26 //! hello-world = Hello, world!
27 //! intro = Welcome, { $name }.
29 //! let res = FluentResource::try_new(ftl_string)
30 //! .expect("Failed to parse an FTL string.");
32 //! let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed");
33 //! let mut bundle = FluentBundle::new(vec![langid_en]);
36 //! .add_resource(res)
37 //! .expect("Failed to add FTL resources to the bundle.");
39 //! let msg = bundle.get_message("hello-world")
40 //! .expect("Message doesn't exist.");
41 //! let mut errors = vec![];
42 //! let pattern = msg.value()
43 //! .expect("Message has no value.");
44 //! let value = bundle.format_pattern(&pattern, None, &mut errors);
46 //! assert_eq!(&value, "Hello, world!");
48 //! let mut args = FluentArgs::new();
49 //! args.set("name", FluentValue::from("John"));
51 //! let msg = bundle.get_message("intro")
52 //! .expect("Message doesn't exist.");
53 //! let mut errors = vec![];
54 //! let pattern = msg.value().expect("Message has no value.");
55 //! let value = bundle.format_pattern(&pattern, Some(&args), &mut errors);
57 //! // The FSI/PDI isolation marks ensure that the direction of
58 //! // the text from the variable is not affected by the translation.
59 //! assert_eq!(value, "Welcome, \u{2068}John\u{2069}.");
62 //! # Ergonomics & Higher Level APIs
64 //! Reading the example, you may notice how verbose it feels.
65 //! Many core methods are fallible, others accumulate errors, and there
66 //! are intermediate structures used in operations.
68 //! This is intentional as it serves as building blocks for variety of different
69 //! scenarios allowing implementations to handle errors, cache and
72 //! At the moment it is expected that users will use
73 //! the `fluent-bundle` crate directly, while the ecosystem
74 //! matures and higher level APIs are being developed.
76 //! [`FluentBundle`]: ./struct.FluentBundle.html
77 //! [`FluentResource`]: ./struct.FluentResource.html
78 //! [`FluentMessage`]: ./struct.FluentMessage.html
79 //! [`FluentArgs`]: ./type.FluentArgs.html
80 //! [`FluentValue`]: ./struct.FluentValue.html
82 pub use fluent_bundle::*;
84 /// A helper macro to simplify creation of FluentArgs.
89 /// use fluent::fluent_args;
91 /// let mut args = fluent_args![
98 macro_rules! fluent_args {
99 ( $($key:expr => $value:expr),* ) => {
101 let mut args: $crate::FluentArgs = $crate::FluentArgs::new();
103 args.set($key, $value);