1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
#![deny(missing_docs)]
#![forbid(unsafe_code)]
#![deny(warnings)]
#![cfg_attr(feature = "nightly", feature(proc_macro_diagnostic, track_path))]
//! # About Leptos i18n macro
//!
//! This crate expose the utility macro for `leptos_i18n`
//!
//! This crate must be used with `leptos_i18n` and should'nt be used outside of it.
pub(crate) mod load_locales;
pub(crate) mod t_macro;
use t_macro::{InputType, OutputType};
// for deserializing the files custom deserialization is done,
// this is to use `serde::de::DeserializeSeed` to pass information on what locale or key we are currently at
// and give better information on what went wrong when an error is emitted.
/// Look for the configuration in the cargo manifest `Cargo.toml` at the root of the project and load the given locales.
///
/// It creates multiple types allowing to easily incorporate translations in you application such as:
///
/// - `Locale`: an enum representing the available locales of the application.
/// - `I18nKeys`: a struct representing the translation keys.
#[proc_macro]
pub fn load_locales(_tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
match load_locales::load_locales() {
Ok(ts) => ts.into(),
Err(err) => err.into(),
}
}
/// Utility macro to easily put translation in your application.
///
/// Usage:
///
/// ```rust, ignore
/// use crate::i18n::*;
///
/// let i18n = use_i18n();
///
/// view! {
/// <p>{t!(i18n, $key)}</p>
/// <p>{t!(i18n, $key, $variable = $value, <$component> = |child| ... )}</p>
/// }
/// ```
///
/// # Notes
///
/// If your variable/component value is the same as the key, you remove the assignement, such that this:
///
/// ```rust, ignore
/// t!(i18n, $key, variable = variable, <component> = component, $other_key = $other_value, ..)
/// ```
///
/// can be shortened to:
///
/// ```rust, ignore
/// t!(i18n, $key, variable, <component>, $other_key = $other_value, ..)
/// ```
#[proc_macro]
pub fn t(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
t_macro::t_macro(tokens, InputType::Context, OutputType::View)
}
/// Just like the `t!` macro but instead of taking `I18nContext` as the first argument it takes the desired locale.
///
/// Usage:
///
/// ```rust, ignore
/// use crate::i18n::*;
///
/// view! {
/// <p>{td!(Locale::en, $key)}</p>
/// <p>{td!(Locale::fr, $key, $variable = $value, <$component> = |child| ... )}</p>
/// }
/// ```
///
/// This let you use a specific locale regardless of the current one.
#[proc_macro]
pub fn td(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
t_macro::t_macro(tokens, InputType::Locale, OutputType::View)
}
/// Just like the `t!` macro but return a `Cow<'static, str>` instead of a view.
///
/// Usage:
///
/// ```rust, ignore
/// use crate::i18n::*;
///
/// let i18n = use_i18n(); // locale = "en"
///
/// // click_count = "You clicked {{ count }} times"
///
/// assert_eq!(
/// t_string!(i18n, click_count, count = 10),
/// "You clicked 10 times"
/// )
///
/// assert_eq!(
/// t_string!(i18n, click_count, count = "a lot of"),
/// "You clicked a lot of times"
/// )
/// ```
#[cfg(feature = "interpolate_display")]
#[proc_macro]
pub fn t_string(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
t_macro::t_macro(tokens, InputType::Context, OutputType::String)
}
/// Just like the `t_string!` macro but return either a struct implementing `Display` or a `&'static str` instead of a `Cow<'static, str>`.
///
/// This is usefull if you will print the value or use it in any formatting operation, as it will avoid a temporary `String`.
///
/// Usage:
///
/// ```rust, ignore
/// use crate::i18n::*;
///
/// let i18n = use_i18n(); // locale = "en"
///
/// // click_count = "You clicked {{ count }} times"
/// let t = t_display!(i18n, click_count, count = 10); // this only return the builder, no work has been done.
///
/// assert_eq!(format!("before {t} after"), "before You clicked 10 times after");
///
/// let t_str = t.to_string(); // can call `to_string` as the value impl `Display`
///
/// assert_eq!(t_str, "You clicked 10 times");
/// ```
#[cfg(feature = "interpolate_display")]
#[proc_macro]
pub fn t_display(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
t_macro::t_macro(tokens, InputType::Context, OutputType::Display)
}
/// Just like the `t_string!` macro but takes the `Locale` as an argument instead of the context.
///
/// Usage:
///
/// ```rust, ignore
/// use crate::i18n::*;
///
/// // click_count = "You clicked {{ count }} times"
/// assert_eq!(
/// td_string!(Locale::en, click_count, count = 10),
/// "You clicked 10 times"
/// )
///
/// assert_eq!(
/// td_string!(Locale::en, click_count, count = "a lot of"),
/// "You clicked a lot of times"
/// )
/// ```
#[cfg(feature = "interpolate_display")]
#[proc_macro]
pub fn td_string(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
t_macro::t_macro(tokens, InputType::Locale, OutputType::String)
}
/// Just like the `t_display!` macro but takes the `Locale` as an argument instead of the context.
///
/// This is usefull if you will print the value or use it in any formatting operation, as it will avoid a temporary `String`.
///
/// Usage:
///
/// ```rust, ignore
/// use crate::i18n::*;
///
/// // click_count = "You clicked {{ count }} times"
/// let t = td_display!(Locale::en, click_count, count = 10); // this only return the builder, no work has been done.
///
/// assert_eq!(format!("before {t} after"), "before You clicked 10 times after");
///
/// let t_str = t.to_string(); // can call `to_string` as the value impl `Display`
///
/// assert_eq!(t_str, "You clicked 10 times");
/// ```
#[cfg(feature = "interpolate_display")]
#[proc_macro]
pub fn td_display(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
t_macro::t_macro(tokens, InputType::Locale, OutputType::Display)
}