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 the 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;