fluent_bundle/
entry.rs

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