Bug 1888590 - Mark some subtests on trusted-types-event-handlers.html as failing...
[gecko.git] / third_party / rust / fluent-bundle / src / message.rs
bloba6cc00d77e8f0f08877a337bbdd294d641c5744a
1 use fluent_syntax::ast;
3 /// [`FluentAttribute`] is a component of a compound [`FluentMessage`].
4 ///
5 /// It represents a key-value pair providing a translation of a component
6 /// of a user interface widget localized by the given message.
7 ///
8 /// # Example
9 ///
10 /// ```
11 /// use fluent_bundle::{FluentResource, FluentBundle};
12 ///
13 /// let source = r#"
14 ///
15 /// confirm-modal = Are you sure?
16 ///     .confirm = Yes
17 ///     .cancel = No
18 ///     .tooltip = Closing the window will lose all unsaved data.
19 ///
20 /// "#;
21 ///
22 /// let resource = FluentResource::try_new(source.to_string())
23 ///     .expect("Failed to parse the resource.");
24 ///
25 /// let mut bundle = FluentBundle::default();
26 /// bundle.add_resource(resource)
27 ///     .expect("Failed to add a resource.");
28 ///
29 /// let msg = bundle.get_message("confirm-modal")
30 ///     .expect("Failed to retrieve a message.");
31 ///
32 /// let mut err = vec![];
33 ///
34 /// let attributes = msg.attributes().map(|attr| {
35 ///     bundle.format_pattern(attr.value(), None, &mut err)
36 /// }).collect::<Vec<_>>();
37 ///
38 /// assert_eq!(attributes[0], "Yes");
39 /// assert_eq!(attributes[1], "No");
40 /// assert_eq!(attributes[2], "Closing the window will lose all unsaved data.");
41 /// ```
42 #[derive(Debug, PartialEq)]
43 pub struct FluentAttribute<'m> {
44     node: &'m ast::Attribute<&'m str>,
47 impl<'m> FluentAttribute<'m> {
48     /// Retrieves an id of an attribute.
49     ///
50     /// # Example
51     ///
52     /// ```
53     /// # use fluent_bundle::{FluentResource, FluentBundle};
54     /// # let source = r#"
55     /// # confirm-modal =
56     /// #     .confirm = Yes
57     /// # "#;
58     /// # let resource = FluentResource::try_new(source.to_string())
59     /// #     .expect("Failed to parse the resource.");
60     /// # let mut bundle = FluentBundle::default();
61     /// # bundle.add_resource(resource)
62     /// #     .expect("Failed to add a resource.");
63     /// let msg = bundle.get_message("confirm-modal")
64     ///     .expect("Failed to retrieve a message.");
65     ///
66     /// let attr1 = msg.attributes().next()
67     ///     .expect("Failed to retrieve an attribute.");
68     ///
69     /// assert_eq!(attr1.id(), "confirm");
70     /// ```
71     pub fn id(&self) -> &'m str {
72         &self.node.id.name
73     }
75     /// Retrieves an value of an attribute.
76     ///
77     /// # Example
78     ///
79     /// ```
80     /// # use fluent_bundle::{FluentResource, FluentBundle};
81     /// # let source = r#"
82     /// # confirm-modal =
83     /// #     .confirm = Yes
84     /// # "#;
85     /// # let resource = FluentResource::try_new(source.to_string())
86     /// #     .expect("Failed to parse the resource.");
87     /// # let mut bundle = FluentBundle::default();
88     /// # bundle.add_resource(resource)
89     /// #     .expect("Failed to add a resource.");
90     /// let msg = bundle.get_message("confirm-modal")
91     ///     .expect("Failed to retrieve a message.");
92     ///
93     /// let attr1 = msg.attributes().next()
94     ///     .expect("Failed to retrieve an attribute.");
95     ///
96     /// let mut err = vec![];
97     ///
98     /// let value = attr1.value();
99     /// assert_eq!(
100     ///     bundle.format_pattern(value, None, &mut err),
101     ///     "Yes"
102     /// );
103     /// ```
104     pub fn value(&self) -> &'m ast::Pattern<&'m str> {
105         &self.node.value
106     }
109 impl<'m> From<&'m ast::Attribute<&'m str>> for FluentAttribute<'m> {
110     fn from(attr: &'m ast::Attribute<&'m str>) -> Self {
111         FluentAttribute { node: attr }
112     }
115 /// [`FluentMessage`] is a basic translation unit of the Fluent system.
117 /// The instance of a message is returned from the
118 /// [`FluentBundle::get_message`](crate::bundle::FluentBundle::get_message)
119 /// method, for the lifetime of the [`FluentBundle`](crate::bundle::FluentBundle) instance.
121 /// # Example
123 /// ```
124 /// use fluent_bundle::{FluentResource, FluentBundle};
126 /// let source = r#"
128 /// hello-world = Hello World!
130 /// "#;
132 /// let resource = FluentResource::try_new(source.to_string())
133 ///     .expect("Failed to parse the resource.");
135 /// let mut bundle = FluentBundle::default();
136 /// bundle.add_resource(resource)
137 ///     .expect("Failed to add a resource.");
139 /// let msg = bundle.get_message("hello-world")
140 ///     .expect("Failed to retrieve a message.");
142 /// assert!(msg.value().is_some());
143 /// ```
145 /// That value can be then passed to
146 /// [`FluentBundle::format_pattern`](crate::bundle::FluentBundle::format_pattern) to be formatted
147 /// within the context of a given [`FluentBundle`](crate::bundle::FluentBundle) instance.
149 /// # Compound Message
151 /// A message may contain a `value`, but it can also contain a list of [`FluentAttribute`] elements.
153 /// If a message contains attributes, it is called a "compound" message.
155 /// In such case, the message contains a list of key-value attributes that represent
156 /// different translation values associated with a single translation unit.
158 /// This is useful for scenarios where a [`FluentMessage`] is associated with a
159 /// complex User Interface widget which has multiple attributes that need to be translated.
160 /// ```text
161 /// confirm-modal = Are you sure?
162 ///     .confirm = Yes
163 ///     .cancel = No
164 ///     .tooltip = Closing the window will lose all unsaved data.
165 /// ```
166 #[derive(Debug, PartialEq)]
167 pub struct FluentMessage<'m> {
168     node: &'m ast::Message<&'m str>,
171 impl<'m> FluentMessage<'m> {
172     /// Retrieves an option of a [`ast::Pattern`](fluent_syntax::ast::Pattern).
173     ///
174     /// # Example
175     ///
176     /// ```
177     /// # use fluent_bundle::{FluentResource, FluentBundle};
178     /// # let source = r#"
179     /// # hello-world = Hello World!
180     /// # "#;
181     /// # let resource = FluentResource::try_new(source.to_string())
182     /// #     .expect("Failed to parse the resource.");
183     /// # let mut bundle = FluentBundle::default();
184     /// # bundle.add_resource(resource)
185     /// #     .expect("Failed to add a resource.");
186     /// let msg = bundle.get_message("hello-world")
187     ///     .expect("Failed to retrieve a message.");
188     ///
189     /// if let Some(value) = msg.value() {
190     ///     let mut err = vec![];
191     ///     assert_eq!(
192     ///         bundle.format_pattern(value, None, &mut err),
193     ///         "Hello World!"
194     ///     );
195     /// #   assert_eq!(err.len(), 0);
196     /// }
197     /// ```
198     pub fn value(&self) -> Option<&'m ast::Pattern<&'m str>> {
199         self.node.value.as_ref()
200     }
202     /// An iterator over [`FluentAttribute`] elements.
203     ///
204     /// # Example
205     ///
206     /// ```
207     /// # use fluent_bundle::{FluentResource, FluentBundle};
208     /// # let source = r#"
209     /// # hello-world =
210     /// #     .label = This is a label
211     /// #     .accesskey = C
212     /// # "#;
213     /// # let resource = FluentResource::try_new(source.to_string())
214     /// #     .expect("Failed to parse the resource.");
215     /// # let mut bundle = FluentBundle::default();
216     /// # bundle.add_resource(resource)
217     /// #     .expect("Failed to add a resource.");
218     /// let msg = bundle.get_message("hello-world")
219     ///     .expect("Failed to retrieve a message.");
220     ///
221     /// let mut err = vec![];
222     ///
223     /// for attr in msg.attributes() {
224     ///     let _ = bundle.format_pattern(attr.value(), None, &mut err);
225     /// }
226     /// # assert_eq!(err.len(), 0);
227     /// ```
228     pub fn attributes(&self) -> impl Iterator<Item = FluentAttribute<'m>> {
229         self.node.attributes.iter().map(Into::into)
230     }
232     /// Retrieve a single [`FluentAttribute`] element.
233     ///
234     /// # Example
235     ///
236     /// ```
237     /// # use fluent_bundle::{FluentResource, FluentBundle};
238     /// # let source = r#"
239     /// # hello-world =
240     /// #     .label = This is a label
241     /// #     .accesskey = C
242     /// # "#;
243     /// # let resource = FluentResource::try_new(source.to_string())
244     /// #     .expect("Failed to parse the resource.");
245     /// # let mut bundle = FluentBundle::default();
246     /// # bundle.add_resource(resource)
247     /// #     .expect("Failed to add a resource.");
248     /// let msg = bundle.get_message("hello-world")
249     ///     .expect("Failed to retrieve a message.");
250     ///
251     /// let mut err = vec![];
252     ///
253     /// if let Some(attr) = msg.get_attribute("label") {
254     ///     assert_eq!(
255     ///         bundle.format_pattern(attr.value(), None, &mut err),
256     ///         "This is a label"
257     ///     );
258     /// }
259     /// # assert_eq!(err.len(), 0);
260     /// ```
261     pub fn get_attribute(&self, key: &str) -> Option<FluentAttribute<'m>> {
262         self.node
263             .attributes
264             .iter()
265             .find(|attr| attr.id.name == key)
266             .map(Into::into)
267     }
270 impl<'m> From<&'m ast::Message<&'m str>> for FluentMessage<'m> {
271     fn from(msg: &'m ast::Message<&'m str>) -> Self {
272         FluentMessage { node: msg }
273     }