1 //! Fluent is a modern localization system designed to improve how software is translated. 2 //! 3 //! `fluent-bundle` is a mid-level component of the [Fluent Localization 4 //! System](https://www.projectfluent.org). 5 //! 6 //! The crate builds on top of the low level [`fluent-syntax`](../fluent-syntax) package, and provides 7 //! foundational types and structures required for executing localization at runtime. 8 //! 9 //! There are four core concepts to understand Fluent runtime: 10 //! 11 //! * [`FluentMessage`] - A single translation unit 12 //! * [`FluentResource`] - A list of [`FluentMessage`] units 13 //! * [`FluentBundle`](crate::bundle::FluentBundle) - A collection of [`FluentResource`] lists 14 //! * [`FluentArgs`] - A list of elements used to resolve a [`FluentMessage`] value 15 //! 16 //! ## Example 17 //! 18 //! ``` 19 //! use fluent_bundle::{FluentBundle, FluentValue, FluentResource, FluentArgs}; 20 //! // Used to provide a locale for the bundle. 21 //! use unic_langid::langid; 22 //! 23 //! // 1. Crate a FluentResource 24 //! 25 //! let ftl_string = r#" 26 //! 27 //! hello-world = Hello, world! 28 //! intro = Welcome, { $name }. 29 //! 30 //! "#.to_string(); 31 //! 32 //! let res = FluentResource::try_new(ftl_string) 33 //! .expect("Failed to parse an FTL string."); 34 //! 35 //! 36 //! // 2. Crate a FluentBundle 37 //! 38 //! let langid_en = langid!("en-US"); 39 //! let mut bundle = FluentBundle::new(vec![langid_en]); 40 //! 41 //! 42 //! // 3. Add the resource to the bundle 43 //! 44 //! bundle 45 //! .add_resource(res) 46 //! .expect("Failed to add FTL resources to the bundle."); 47 //! 48 //! 49 //! // 4. Retrieve a FluentMessage from the bundle 50 //! 51 //! let msg = bundle.get_message("hello-world") 52 //! .expect("Message doesn't exist."); 53 //! 54 //! 55 //! // 5. Format the value of the simple message 56 //! 57 //! let mut errors = vec![]; 58 //! 59 //! let pattern = msg.value() 60 //! .expect("Message has no value."); 61 //! 62 //! let value = bundle.format_pattern(&pattern, None, &mut errors); 63 //! 64 //! assert_eq!( 65 //! bundle.format_pattern(&pattern, None, &mut errors), 66 //! "Hello, world!" 67 //! ); 68 //! 69 //! // 6. Format the value of the message with arguments 70 //! 71 //! let mut args = FluentArgs::new(); 72 //! args.set("name", "John"); 73 //! 74 //! let msg = bundle.get_message("intro") 75 //! .expect("Message doesn't exist."); 76 //! 77 //! let pattern = msg.value() 78 //! .expect("Message has no value."); 79 //! 80 //! // The FSI/PDI isolation marks ensure that the direction of 81 //! // the text from the variable is not affected by the translation. 82 //! assert_eq!( 83 //! bundle.format_pattern(&pattern, Some(&args), &mut errors), 84 //! "Welcome, \u{2068}John\u{2069}." 85 //! ); 86 //! ``` 87 //! 88 //! # Ergonomics & Higher Level APIs 89 //! 90 //! Reading the example, you may notice how verbose it feels. 91 //! Many core methods are fallible, others accumulate errors, and there 92 //! are intermediate structures used in operations. 93 //! 94 //! This is intentional as it serves as building blocks for variety of different 95 //! scenarios allowing implementations to handle errors, cache and 96 //! optimize results. 97 //! 98 //! At the moment it is expected that users will use 99 //! the `fluent-bundle` crate directly, while the ecosystem 100 //! matures and higher level APIs are being developed. 101 mod args; 102 pub mod bundle; 103 mod concurrent; 104 mod entry; 105 mod errors; 106 #[doc(hidden)] 107 pub mod memoizer; 108 mod message; 109 #[doc(hidden)] 110 pub mod resolver; 111 mod resource; 112 pub mod types; 113 114 pub use args::FluentArgs; 115 /// Specialized [`FluentBundle`](crate::bundle::FluentBundle) over 116 /// non-concurrent [`IntlLangMemoizer`](intl_memoizer::IntlLangMemoizer). 117 /// 118 /// This is the basic variant of the [`FluentBundle`](crate::bundle::FluentBundle). 119 /// 120 /// The concurrent specialization, can be constructed with 121 /// [`FluentBundle::new_concurrent`](crate::bundle::FluentBundle::new_concurrent). 122 pub type FluentBundle<R> = bundle::FluentBundle<R, intl_memoizer::IntlLangMemoizer>; 123 pub use errors::FluentError; 124 pub use message::{FluentAttribute, FluentMessage}; 125 pub use resource::FluentResource; 126 #[doc(inline)] 127 pub use types::FluentValue; 128