By default, custom formatters might require values to implement Display. If you pass a Leptos Signal via a closure (e.g., t!(i18n, my_fmt, var = || signal.get())), the compiler may error because the closure itself does not implement Display.
To support reactivity, you can define a custom trait in your crate that accepts any function returning a Display type, and use that trait in your view_bounds and to_view implementations.
- Define a helper trait:
pub trait ToDisplayFn: 'static + Clone + Send + Sync {
type Value: Display;
fn to_value(&self) -> Self::Value;
}
impl<T: Display, F> ToDisplayFn for F
where
F: Fn() -> T + 'static + Clone + Send + Sync,
{
type Value = T;
fn to_value(&self) -> Self::Value {
self()
}
}
- Use it in
view_bounds:
fn view_bounds(&self) -> TokenStream {
quote!(crate::ToDisplayFn)
}
- Use it in
to_view:
fn to_view(&self, key: &syn::Ident, locale_field: &syn::Ident) -> TokenStream {
quote! {
move || {
std::format!(#fmt_string, crate::ToDisplayFn::to_value(&#key))
}
}
}