local_fmt/
macros.rs

1use local_fmt_macros::gen_static_message;
2use sealed::Sealed;
3
4use crate::{panic_builder, StaticMessage};
5
6mod sealed {
7    use crate::StaticMessage;
8
9    pub trait Sealed {}
10
11    impl Sealed for &'static str {}
12    impl<const N: usize> Sealed for StaticMessage<N> {}
13}
14
15pub trait CheckStaticMessageArg<To>: Sealed {
16    const IS_INVALID: Option<StaticMessage<2>>;
17}
18
19/// Checks if the message argument is valid.
20/// If the argument is invalid, a panic is raised with a detailed error message.
21/// Otherwise, the argument is returned.
22#[track_caller]
23pub const fn check_static_message_arg<To, From>(
24    lang: &'static str,
25    key: &'static str,
26    from: &From,
27) -> To
28where
29    From: CheckStaticMessageArg<To>,
30{
31    if let Some(message) = From::IS_INVALID {
32        panic_builder!(message, [lang], [key]);
33    }
34    unsafe { std::ptr::read(from as *const From as *const To) }
35}
36
37impl CheckStaticMessageArg<&'static str> for &'static str {
38    const IS_INVALID: Option<StaticMessage<2>> = None;
39}
40
41impl<const N: usize, const M: usize> CheckStaticMessageArg<StaticMessage<N>> for StaticMessage<M> {
42    const IS_INVALID: Option<StaticMessage<2>> = if N == M {
43        None
44    } else {
45        Some(gen_static_message!(
46            "Error: A message with {u:M} arguments was expected in the language '{0}', ",
47            "but received a message with {u:N} arguments for the key '{1}'. ",
48            "Please check the message definition and ensure the correct number of arguments."
49        ))
50    };
51}
52
53impl<const N: usize> CheckStaticMessageArg<&'static str> for StaticMessage<N> {
54    const IS_INVALID: Option<StaticMessage<2>> = Some(gen_static_message!(
55        "Error: A message with {u:N} arguments was expected in the language '{0}', ",
56        "but received a message with no arguments for the key '{1}'. ",
57        "Please check the message definition and ensure the correct number of arguments."
58    ));
59}
60
61impl<const N: usize> CheckStaticMessageArg<StaticMessage<N>> for &'static str {
62    const IS_INVALID: Option<StaticMessage<2>> = Some(gen_static_message!(
63        "Error: A message with {u:N} arguments was expected in the language '{0}', ",
64        "but received a message with no arguments for the key '{1}'. ",
65        "Please check the message definition and ensure the correct number of arguments."
66    ));
67}