Skip to main content

cranpose_localization/
deferred.rs

1use std::rc::Rc;
2
3use crate::{Argument, LocalizationError, Message, Translator};
4
5/// A message captured outside composition and translated when displayed.
6/// Borrowed arguments become owned; cloning a request shares their storage.
7/// Use `message!` to construct one with checked source text and named arguments.
8#[derive(Clone)]
9pub struct DeferredMessage {
10    message: &'static Message,
11    arguments: Option<Rc<[Argument<'static>]>>,
12}
13
14impl DeferredMessage {
15    /// Captures arguments for a checked static message without formatting it.
16    pub fn new<const N: usize>(message: &'static Message, arguments: [Argument<'_>; N]) -> Self {
17        Self {
18            message,
19            arguments: (N != 0).then(|| {
20                arguments
21                    .into_iter()
22                    .map(|mut argument| argument.take_owned())
23                    .collect()
24            }),
25        }
26    }
27
28    /// Formats with the current application translator, or the source language.
29    pub fn format(&self, translator: Option<&Translator>) -> Result<String, LocalizationError> {
30        let arguments = self.arguments.as_deref().unwrap_or_default();
31        match translator {
32            Some(translator) => translator.format(self.message, arguments),
33            None => self.message.format_source(arguments),
34        }
35    }
36
37    /// Readable source text when a malformed runtime catalog cannot be formatted.
38    pub fn fallback_text(&self) -> String {
39        self.message
40            .fallback_text(self.arguments.as_deref().unwrap_or_default())
41    }
42}
43
44impl PartialEq for DeferredMessage {
45    fn eq(&self, other: &Self) -> bool {
46        std::ptr::eq(self.message, other.message) && self.arguments == other.arguments
47    }
48}
49
50impl std::fmt::Debug for DeferredMessage {
51    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52        formatter
53            .debug_struct("DeferredMessage")
54            .field("namespace", &self.message.namespace())
55            .field("id", &self.message.id())
56            .field("arguments", &self.arguments)
57            .finish()
58    }
59}