[−][src]Struct fluent_bundle::FluentBundle
A collection of localization messages for a single locale, which are meant to be used together in a single view, widget or any other UI abstraction.
Examples
use fluent_bundle::{FluentBundle, FluentResource, FluentValue}; use std::collections::HashMap; use unic_langid::langid; let ftl_string = String::from("intro = Welcome, { $name }."); let resource = FluentResource::try_new(ftl_string) .expect("Could not parse an FTL string."); let langid_en = langid!("en-US"); let mut bundle = FluentBundle::new(&[langid_en]); bundle.add_resource(&resource) .expect("Failed to add FTL resources to the bundle."); let mut args = HashMap::new(); args.insert("name", FluentValue::from("Rustacean")); let msg = bundle.get_message("intro").expect("Message doesn't exist."); let mut errors = vec![]; let pattern = msg.value.expect("Message has no value."); let value = bundle.format_pattern(&pattern, Some(&args), &mut errors); assert_eq!(&value, "Welcome, \u{2068}Rustacean\u{2069}.");
FluentBundle
Life Cycle
Create a bundle
To create a bundle, call FluentBundle::new
with a locale list that represents the best
possible fallback chain for a given locale. The simplest case is a one-locale list.
Fluent uses LanguageIdentifier
which can be created using langid!
macro.
Add Resources
Next, call add_resource
one or more times, supplying translations in the FTL syntax.
Since FluentBundle
is generic over anything that can borrow a FluentResource
,
one can use FluentBundle
to own its resources, store references to them,
or even Rc<FluentResource>
or Arc<FluentResource>
.
The FluentBundle
instance is now ready to be used for localization.
Format
To format a translation, call get_message
to retrieve a FluentMessage
,
and then call format_pattern
on the message value or attribute in order to
retrieve the translated string.
The result of format_pattern
is an Cow<str>
. It is
recommended to treat the result as opaque from the perspective of the program and use it only
to display localized messages. Do not examine it or alter in any way before displaying. This
is a general good practice as far as all internationalization operations are concerned.
If errors were encountered during formatting, they will be
accumulated in the Vec<FluentError>
passed as the third argument.
While they are not fatal, they usually indicate problems with the translation, and should be logged or reported in a way that allows the developer to notice and fix them.
Locale Fallback Chain
FluentBundle
stores messages in a single locale, but keeps a locale fallback chain for the
purpose of language negotiation with i18n formatters. For instance, if date and time formatting
are not available in the first locale, FluentBundle
will use its locales
fallback chain
to negotiate a sensible fallback for date and time formatting.
Fields
locales: Vec<LanguageIdentifier>
Methods
impl<R> FluentBundle<R>
[src]
pub fn new<'a, L: 'a + Into<LanguageIdentifier> + PartialEq + Clone>(
locales: impl IntoIterator<Item = &'a L>
) -> Self
[src]
locales: impl IntoIterator<Item = &'a L>
) -> Self
Constructs a FluentBundle. locales
is the fallback chain of locales
to use for formatters like date and time. locales
does not influence
message selection.
Examples
use fluent_bundle::FluentBundle; use fluent_bundle::FluentResource; use unic_langid::langid; let langid_en = langid!("en-US"); let mut bundle: FluentBundle<FluentResource> = FluentBundle::new(&[langid_en]);
Errors
This will panic if no formatters can be found for the locales.
pub fn add_resource(&mut self, r: R) -> Result<(), Vec<FluentError>> where
R: Borrow<FluentResource>,
[src]
R: Borrow<FluentResource>,
Adds a resource to the bundle, returning an empty Result<T>
on success.
The method can take any type that can be borrowed to FluentResource:
- FluentResource
- &FluentResource
- Rc
- Arc
This allows the user to introduce custom resource management and share
resources between instances of FluentBundle
.
Examples
use fluent_bundle::{FluentBundle, FluentResource}; use unic_langid::langid; let ftl_string = String::from(" hello = Hi! goodbye = Bye! "); let resource = FluentResource::try_new(ftl_string) .expect("Could not parse an FTL string."); let langid_en = langid!("en-US"); let mut bundle = FluentBundle::new(&[langid_en]); bundle.add_resource(resource) .expect("Failed to add FTL resources to the bundle."); assert_eq!(true, bundle.has_message("hello"));
Whitespace
Message ids must have no leading whitespace. Message values that span
multiple lines must have leading whitespace on all but the first line. These
are standard FTL syntax rules that may prove a bit troublesome in source
code formatting. The indoc!
crate can help with stripping extra indentation
if you wish to indent your entire message.
pub fn set_use_isolating(&mut self, value: bool)
[src]
When formatting patterns, FluentBundle
inserts
Unicode Directionality Isolation Marks to indicate
that the direction of a placeable may differ from
the surrounding message.
This is important for cases such as when a right-to-left user name is presented in the left-to-right message.
In some cases, such as testing, the user may want to disable the isolating.
pub fn set_transform<F>(&mut self, func: Option<F>) where
F: Fn(&str) -> Cow<str> + Send + Sync + 'static,
[src]
F: Fn(&str) -> Cow<str> + Send + Sync + 'static,
This method allows to specify a function that will be called on all textual fragments of the pattern during formatting.
This is currently primarly used for pseudolocalization,
and fluent-pseudo
crate provides a function
that can be passed here.
pub fn has_message(&self, id: &str) -> bool where
R: Borrow<FluentResource>,
[src]
R: Borrow<FluentResource>,
Returns true if this bundle contains a message with the given id.
Examples
use fluent_bundle::{FluentBundle, FluentResource}; use unic_langid::langid; let ftl_string = String::from("hello = Hi!"); let resource = FluentResource::try_new(ftl_string) .expect("Failed to parse an FTL string."); let langid_en = langid!("en-US"); let mut bundle = FluentBundle::new(&[langid_en]); bundle.add_resource(&resource) .expect("Failed to add FTL resources to the bundle."); assert_eq!(true, bundle.has_message("hello"));
pub fn get_message(&self, id: &str) -> Option<FluentMessage> where
R: Borrow<FluentResource>,
[src]
R: Borrow<FluentResource>,
pub fn format_pattern<'bundle>(
&'bundle self,
pattern: &'bundle Pattern,
args: Option<&'bundle FluentArgs>,
errors: &mut Vec<FluentError>
) -> Cow<'bundle, str> where
R: Borrow<FluentResource>,
[src]
&'bundle self,
pattern: &'bundle Pattern,
args: Option<&'bundle FluentArgs>,
errors: &mut Vec<FluentError>
) -> Cow<'bundle, str> where
R: Borrow<FluentResource>,
pub fn add_function<F>(&mut self, id: &str, func: F) -> Result<(), FluentError> where
F: for<'a> Fn(&[FluentValue<'a>], &FluentArgs) -> FluentValue<'a> + Sync + Send + 'static,
[src]
F: for<'a> Fn(&[FluentValue<'a>], &FluentArgs) -> FluentValue<'a> + Sync + Send + 'static,
Makes the provided rust function available to messages with the name id
. See
the FTL syntax guide to learn how these are used in messages.
FTL functions accept both positional and named args. The rust function you provide therefore has two parameters: a slice of values for the positional args, and a HashMap of values for named args.
Examples
use fluent_bundle::{FluentBundle, FluentResource, FluentValue}; use unic_langid::langid; let ftl_string = String::from("length = { STRLEN(\"12345\") }"); let resource = FluentResource::try_new(ftl_string) .expect("Could not parse an FTL string."); let langid_en = langid!("en-US"); let mut bundle = FluentBundle::new(&[langid_en]); bundle.add_resource(&resource) .expect("Failed to add FTL resources to the bundle."); // Register a fn that maps from string to string length bundle.add_function("STRLEN", |positional, _named| match positional { [FluentValue::String(str)] => FluentValue::Number(str.len().to_string().into()), _ => FluentValue::None, }).expect("Failed to add a function to the bundle."); let msg = bundle.get_message("length").expect("Message doesn't exist."); let mut errors = vec![]; let pattern = msg.value.expect("Message has no value."); let value = bundle.format_pattern(&pattern, None, &mut errors); assert_eq!(&value, "5");
Trait Implementations
impl<R> Default for FluentBundle<R>
[src]
Auto Trait Implementations
impl<R> Send for FluentBundle<R> where
R: Send,
R: Send,
impl<R> Unpin for FluentBundle<R> where
R: Unpin,
R: Unpin,
impl<R> Sync for FluentBundle<R> where
R: Sync,
R: Sync,
impl<R> !UnwindSafe for FluentBundle<R>
impl<R> !RefUnwindSafe for FluentBundle<R>
Blanket Implementations
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> From<T> for T
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,