Skip to main content

corundum_framework_gui/i18n/
message.rs

1//! Text decided outside egui: a message id and its arguments, resolved where it is drawn.
2
3use fluent_bundle::FluentValue;
4
5/// A message to show: its id and arguments, for [`text`](Self::text) to look up in the
6/// installed language. Plain functions tested without egui return this rather than text.
7#[derive(Clone, PartialEq, Debug)]
8pub struct Message {
9    /// The message id, as in the `.ftl` files.
10    pub id: &'static str,
11    /// The arguments, by name.
12    pub args: Vec<(&'static str, Arg)>,
13}
14
15impl Message {
16    /// The message `id`, with no arguments yet.
17    pub fn new(id: &'static str) -> Message {
18        Message {
19            id,
20            args: Vec::new(),
21        }
22    }
23
24    /// Add the argument `name`.
25    pub fn arg(mut self, name: &'static str, value: impl Into<Arg>) -> Message {
26        self.args.push((name, value.into()));
27        self
28    }
29
30    /// The text, in the language installed in `ctx`. See [`tr_args`](super::tr_args).
31    pub fn text(&self, ctx: &egui::Context) -> String {
32        super::tr_args(ctx, self.id, &self.args)
33    }
34}
35
36/// A message argument: text, or a number (which selects plural forms).
37#[derive(Clone, PartialEq, Debug)]
38pub enum Arg {
39    /// Text, as is.
40    Str(String),
41    /// A number; Fluent picks plural forms by it.
42    Num(f64),
43}
44
45impl Arg {
46    pub(super) fn to_fluent(&self) -> FluentValue<'_> {
47        match self {
48            Arg::Str(s) => FluentValue::from(s.as_str()),
49            Arg::Num(n) => FluentValue::from(*n),
50        }
51    }
52}
53
54impl From<String> for Arg {
55    fn from(s: String) -> Arg {
56        Arg::Str(s)
57    }
58}
59
60impl From<&str> for Arg {
61    fn from(s: &str) -> Arg {
62        Arg::Str(s.to_owned())
63    }
64}
65
66impl From<f64> for Arg {
67    fn from(n: f64) -> Arg {
68        Arg::Num(n)
69    }
70}
71
72/// Numbers past 2^53 lose precision, as any count shown to a person can afford.
73macro_rules! from_number {
74    ($($t:ty),*) => {$(
75        impl From<$t> for Arg {
76            #[allow(clippy::cast_precision_loss)]
77            fn from(n: $t) -> Arg {
78                Arg::Num(n as f64)
79            }
80        }
81    )*};
82}
83
84from_number!(i32, i64, u32, u64, usize);