locale now does matching against supported

This commit is contained in:
Maccesch 2024-07-29 01:06:00 +01:00
parent 1945e94da1
commit 709757996e
3 changed files with 47 additions and 44 deletions

View file

@ -4,7 +4,7 @@ use leptos_use::use_locale;
#[component] #[component]
fn Demo() -> impl IntoView { fn Demo() -> impl IntoView {
let locale = use_locale(); let locale = use_locale(["en", "de", "fr"]);
view! { view! {
<p>Locale: <code class="font-bold">{locale}</code></p> <p>Locale: <code class="font-bold">{locale}</code></p>

View file

@ -1,14 +1,14 @@
use crate::utils::get_header;
use crate::{use_locales_with_options, UseLocalesOptions}; use crate::{use_locales_with_options, UseLocalesOptions};
use default_struct_builder::DefaultBuilder;
use leptos::*; use leptos::*;
use std::rc::Rc;
/// Reactive locale. /// Reactive locale matching.
/// ///
/// This is basically the same as [`fn@crate::use_locales`] but takes the first entry of the list. /// Returns the first matching locale given by [`fn@crate::use_locales`] that is also found in
/// If no locale is found then [`crate::UseLocaleOptions::fallback`] is returned which defaults /// the `supported` list. In case there is no match, then the first locale in `supported` will be
/// to `"en"`. /// returned. If `supported` is empty, the empty string is returned.
///
/// Matching is done by checking if an accepted locale from `use_locales` starts with a supported
/// locale. If a match is found the locale from the `supported` list is returned.
/// ///
/// ## Demo /// ## Demo
/// ///
@ -22,7 +22,7 @@ use std::rc::Rc;
/// # /// #
/// # #[component] /// # #[component]
/// # fn Demo() -> impl IntoView { /// # fn Demo() -> impl IntoView {
/// let locale = use_locale(); /// let locale = use_locale(&["en".to_string(), "de".to_string(), "fr".to_string()]);
/// # /// #
/// # view! { } /// # view! { }
/// # } /// # }
@ -31,44 +31,47 @@ use std::rc::Rc;
/// ## Server-Side Rendering /// ## Server-Side Rendering
/// ///
/// See [`fn@crate::use_locales`] /// See [`fn@crate::use_locales`]
pub fn use_locale<S>(supported: S) -> Signal<String>
pub fn use_locale() -> Signal<String> { where
use_locale_with_options(UseLocaleOptions::default()) S: IntoIterator,
S::Item: Into<String> + Clone + 'static,
{
use_locale_with_options(supported, UseLocaleOptions::default())
} }
/// Version of [`fn@crate::use_locale`] that takes a `UseLocaleOptions`. See [`fn@crate::use_locale`] for how to use. /// Version of [`fn@crate::use_locale`] that takes a `UseLocaleOptions`. See [`fn@crate::use_locale`] for how to use.
pub fn use_locale_with_options(options: UseLocaleOptions) -> Signal<String> { pub fn use_locale_with_options<S>(supported: S, options: UseLocaleOptions) -> Signal<String>
let UseLocaleOptions { where
fallback, S: IntoIterator,
ssr_lang_header_getter, S::Item: Into<String> + Clone + 'static,
} = options; {
let locales = use_locales_with_options(options);
let locales = use_locales_with_options(UseLocalesOptions { let supported = supported.into_iter().collect::<Vec<_>>();
ssr_lang_header_getter,
});
Signal::derive(move || locales.get().first().cloned().unwrap_or(fallback.clone())) Signal::derive(move || {
} let supported = supported.clone();
/// Options for [`fn@crate::use_locale_with_options`]. locales.with(|locales| {
#[derive(DefaultBuilder)] let mut first_supported = None;
pub struct UseLocaleOptions {
/// Fallback value in case no locale is found. Defaults to `"en"`.
fallback: String,
/// Getter function to return the string value of the accept languange header. for s in supported {
/// When you use one of the features `"axum"`, `"actix"` or `"spin"` there's a valid default implementation provided. let s = s.into();
#[allow(dead_code)]
ssr_lang_header_getter: Rc<dyn Fn() -> Option<String>>,
}
impl Default for UseLocaleOptions { if first_supported.is_none() {
fn default() -> Self { first_supported = Some(s.clone());
Self { }
fallback: "en".to_string(),
ssr_lang_header_getter: Rc::new(move || { for locale in locales {
get_header!(ACCEPT_LANGUAGE, use_locale, ssr_lang_header_getter) if locale.starts_with(&s) {
}), return s;
} }
} }
}
first_supported.unwrap_or_else(|| "".to_string())
})
})
} }
pub type UseLocaleOptions = UseLocalesOptions;

View file

@ -100,7 +100,7 @@ pub struct UseLocalesOptions {
/// Getter function to return the string value of the accept languange header. /// Getter function to return the string value of the accept languange header.
/// When you use one of the features `"axum"`, `"actix"` or `"spin"` there's a valid default implementation provided. /// When you use one of the features `"axum"`, `"actix"` or `"spin"` there's a valid default implementation provided.
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) ssr_lang_header_getter: Rc<dyn Fn() -> Option<String>>, ssr_lang_header_getter: Rc<dyn Fn() -> Option<String>>,
} }
impl Default for UseLocalesOptions { impl Default for UseLocalesOptions {