fluent/lib.rs
1//! Fluent is a modern localization system designed to improve how software is translated.
2//!
3//! The Rust implementation provides the low level components for syntax operations, like parser
4//! and AST, and the core localization struct - [`FluentBundle`].
5//!
6//! [`FluentBundle`] is the low level container for storing and formatting localization messages
7//! in a single locale.
8//!
9//! This crate provides also a number of structures needed for a localization API such as [`FluentResource`],
10//! [`FluentMessage`], [`FluentArgs`], and [`FluentValue`].
11//!
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.
16//!
17//! # Example
18//!
19//! ```
20//! use fluent::{FluentBundle, FluentValue, FluentResource, FluentArgs};
21//!
22//! // Used to provide a locale for the bundle.
23//! use unic_langid::LanguageIdentifier;
24//!
25//! let ftl_string = String::from("
26//! hello-world = Hello, world!
27//! intro = Welcome, { $name }.
28//! ");
29//! let res = FluentResource::try_new(ftl_string)
30//! .expect("Failed to parse an FTL string.");
31//!
32//! let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed");
33//! let mut bundle = FluentBundle::new(vec![langid_en]);
34//!
35//! bundle
36//! .add_resource(res)
37//! .expect("Failed to add FTL resources to the bundle.");
38//!
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);
45//!
46//! assert_eq!(&value, "Hello, world!");
47//!
48//! let mut args = FluentArgs::new();
49//! args.set("name", FluentValue::from("John"));
50//!
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);
56//!
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}.");
60//! ```
61//!
62//! # Ergonomics & Higher Level APIs
63//!
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.
67//!
68//! This is intentional as it serves as building blocks for variety of different
69//! scenarios allowing implementations to handle errors, cache and
70//! optimize results.
71//!
72//! At the moment it is expected that users will use
73//! the [`fluent-bundle`](fluent_bundle) crate directly, while the ecosystem
74//! matures and higher level APIs are being developed.
75//!
76//! [`FluentBundle`]: bundle::FluentBundle
77
78pub use fluent_bundle::*;
79
80/// A helper macro to simplify creation of `FluentArgs`.
81///
82/// # Example
83///
84/// ```
85/// use fluent::fluent_args;
86///
87/// let mut args = fluent_args![
88/// "name" => "John",
89/// "emailCount" => 5,
90/// ];
91///
92/// ```
93#[macro_export]
94macro_rules! fluent_args {
95 ( $($key:expr => $value:expr),* $(,)? ) => {
96 {
97 let mut args: $crate::FluentArgs = $crate::FluentArgs::new();
98 $(
99 args.set($key, $value);
100 )*
101 args
102 }
103 };
104}