Framework for embedding localizations into Rust types
//! End-to-end tests for the examples at https://projectfluent.org/fluent/guide/placeables.html

mod common;

use common::compare_message;
use icu_locale::{Locale, locale};
use l10n_embed_derive::localize;
use rstest::rstest;

const DEFAULT_LOCALE: Locale = locale!("en-US");

#[localize("tests/locale/**/placeables.ftl")]
pub enum Message {
    OpenTabs { quantity: u64 },
    Person { name: String },
    TabStatus { name: String, quantity: u64 },
}

#[localize("tests/locale/**/placeables.ftl")]
pub struct OpenTabs {
    quantity: u64,
}

#[localize("tests/locale/**/placeables.ftl")]
pub struct Person {
    name: String,
}

#[localize("tests/locale/**/placeables.ftl")]
pub struct TabStatus {
    name: String,
    quantity: u64,
}

#[rstest]
#[case::zero(0_u64, "0")]
#[case::two(2_u64, "2")]
#[case::max(u64::MAX, "18,446,744,073,709,551,615")]
fn number(#[case] quantity: u64, #[case] expected: String) {
    let expected = format!("{expected} tabs open.");

    compare_message(OpenTabs { quantity }, &expected, DEFAULT_LOCALE);
    compare_message(Message::OpenTabs { quantity }, expected, DEFAULT_LOCALE);
}

#[rstest]
#[case::empty("")]
#[case::single_hyphen(r#"""#)]
#[case::english("Ferris")]
#[case::accent("Férris")]
#[case::unicode("")]
fn string(#[case] name: String) {
    let expected = format!("How many tabs does {name} have open?");

    compare_message(Person { name: name.clone() }, &expected, DEFAULT_LOCALE);
    compare_message(Message::Person { name }, expected, DEFAULT_LOCALE);
}

#[rstest]
#[case::empty(0_u64, "0", "")]
#[case::simple(2_u64, "2", "Ferris")]
#[case::complex(u64::MAX, "18,446,744,073,709,551,615", "")]
fn numbers_and_strings(#[case] quantity: u64, #[case] tab_count: String, #[case] name: String) {
    let expected = format!("{name} has {tab_count} tabs open!");

    compare_message(
        TabStatus {
            name: name.clone(),
            quantity,
        },
        &expected,
        DEFAULT_LOCALE,
    );
    compare_message(
        Message::TabStatus { name, quantity },
        expected,
        DEFAULT_LOCALE,
    );
}