1 | //! `Entry` is used to store Messages, Terms and Functions in `FluentBundle` instances. |
2 | |
3 | use std::borrow::Borrow; |
4 | |
5 | use fluent_syntax::ast; |
6 | |
7 | use crate::args::FluentArgs; |
8 | use crate::bundle::FluentBundle; |
9 | use crate::resource::FluentResource; |
10 | use crate::types::FluentValue; |
11 | |
12 | pub type FluentFunction = |
13 | Box<dyn for<'a> Fn(&[FluentValue<'a>], &FluentArgs) -> FluentValue<'a> + Send + Sync>; |
14 | |
15 | pub enum Entry { |
16 | Message((usize, usize)), |
17 | Term((usize, usize)), |
18 | Function(FluentFunction), |
19 | } |
20 | |
21 | pub trait GetEntry { |
22 | fn get_entry_message(&self, id: &str) -> Option<&ast::Message<&str>>; |
23 | fn get_entry_term(&self, id: &str) -> Option<&ast::Term<&str>>; |
24 | fn get_entry_function(&self, id: &str) -> Option<&FluentFunction>; |
25 | } |
26 | |
27 | impl<'bundle, R: Borrow<FluentResource>, M> GetEntry for FluentBundle<R, M> { |
28 | fn get_entry_message(&self, id: &str) -> Option<&ast::Message<&str>> { |
29 | self.entries.get(id).and_then(|ref entry| match entry { |
30 | Entry::Message(pos) => { |
31 | let res = self.resources.get(pos.0)?.borrow(); |
32 | if let ast::Entry::Message(ref msg) = res.get_entry(pos.1)? { |
33 | Some(msg) |
34 | } else { |
35 | None |
36 | } |
37 | } |
38 | _ => None, |
39 | }) |
40 | } |
41 | |
42 | fn get_entry_term(&self, id: &str) -> Option<&ast::Term<&str>> { |
43 | self.entries.get(id).and_then(|ref entry| match entry { |
44 | Entry::Term(pos) => { |
45 | let res = self.resources.get(pos.0)?.borrow(); |
46 | if let ast::Entry::Term(ref msg) = res.get_entry(pos.1)? { |
47 | Some(msg) |
48 | } else { |
49 | None |
50 | } |
51 | } |
52 | _ => None, |
53 | }) |
54 | } |
55 | |
56 | fn get_entry_function(&self, id: &str) -> Option<&FluentFunction> { |
57 | self.entries.get(id).and_then(|ref entry| match entry { |
58 | Entry::Function(function) => Some(function), |
59 | _ => None, |
60 | }) |
61 | } |
62 | } |
63 | |