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
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//! Fluent is a modern localization system designed to improve how software is translated.
//!
//! `fluent-bundle` is a mid-level component of the [Fluent Localization
//! System](https://www.projectfluent.org).
//!
//! The crate builds on top of the low level [`fluent-syntax`](../fluent-syntax) package, and provides
//! foundational types and structures required for executing localization at runtime.
//!
//! There are four core concepts to understand Fluent runtime:
//!
//! * [`FluentMessage`] - A single translation unit
//! * [`FluentResource`] - A list of [`FluentMessage`] units
//! * [`FluentBundle`](crate::bundle::FluentBundle) - A collection of [`FluentResource`] lists
//! * [`FluentArgs`] - A list of elements used to resolve a [`FluentMessage`] value
//!
//! ## Example
//!
//! ```
//! use fluent_bundle::{FluentBundle, FluentValue, FluentResource, FluentArgs};
//! // Used to provide a locale for the bundle.
//! use unic_langid::langid;
//!
//! // 1. Crate a FluentResource
//!
//! let ftl_string = r#"
//!
//! hello-world = Hello, world!
//! intro = Welcome, { $name }.
//!
//! "#.to_string();
//!
//! let res = FluentResource::try_new(ftl_string)
//!     .expect("Failed to parse an FTL string.");
//!
//!
//! // 2. Crate a FluentBundle
//!
//! let langid_en = langid!("en-US");
//! let mut bundle = FluentBundle::new(vec![langid_en]);
//!
//!
//! // 3. Add the resource to the bundle
//!
//! bundle
//!     .add_resource(res)
//!     .expect("Failed to add FTL resources to the bundle.");
//!
//!
//! // 4. Retrieve a FluentMessage from the bundle
//!
//! let msg = bundle.get_message("hello-world")
//!     .expect("Message doesn't exist.");
//!
//!
//! // 5. Format the value of the simple message
//!
//! let mut errors = vec![];
//!
//! let pattern = msg.value()
//!     .expect("Message has no value.");
//!
//! let value = bundle.format_pattern(&pattern, None, &mut errors);
//!
//! assert_eq!(
//!     bundle.format_pattern(&pattern, None, &mut errors),
//!     "Hello, world!"
//! );
//!
//! // 6. Format the value of the message with arguments
//!
//! let mut args = FluentArgs::new();
//! args.set("name", "John");
//!
//! let msg = bundle.get_message("intro")
//!     .expect("Message doesn't exist.");
//!
//! let pattern = msg.value()
//!     .expect("Message has no value.");
//!
//! // The FSI/PDI isolation marks ensure that the direction of
//! // the text from the variable is not affected by the translation.
//! assert_eq!(
//!     bundle.format_pattern(&pattern, Some(&args), &mut errors),
//!     "Welcome, \u{2068}John\u{2069}."
//! );
//! ```
//!
//! # Ergonomics & Higher Level APIs
//!
//! Reading the example, you may notice how verbose it feels.
//! Many core methods are fallible, others accumulate errors, and there
//! are intermediate structures used in operations.
//!
//! This is intentional as it serves as building blocks for variety of different
//! scenarios allowing implementations to handle errors, cache and
//! optimize results.
//!
//! At the moment it is expected that users will use
//! the `fluent-bundle` crate directly, while the ecosystem
//! matures and higher level APIs are being developed.
mod args;
pub mod bundle;
mod concurrent;
mod entry;
mod errors;
#[doc(hidden)]
pub mod memoizer;
mod message;
#[doc(hidden)]
pub mod resolver;
mod resource;
pub mod types;

pub use args::FluentArgs;
/// Specialized [`FluentBundle`](crate::bundle::FluentBundle) over
/// non-concurrent [`IntlLangMemoizer`](intl_memoizer::IntlLangMemoizer).
///
/// This is the basic variant of the [`FluentBundle`](crate::bundle::FluentBundle).
///
/// The concurrent specialization, can be constructed with
/// [`FluentBundle::new_concurrent`](crate::bundle::FluentBundle::new_concurrent).
pub type FluentBundle<R> = bundle::FluentBundle<R, intl_memoizer::IntlLangMemoizer>;
pub use errors::FluentError;
pub use message::{FluentAttribute, FluentMessage};
pub use resource::FluentResource;
#[doc(inline)]
pub use types::FluentValue;