Framework for embedding localizations into Rust types
//! End-to-end test for function support in the `l10n_embed_derive` macro

mod common;

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

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

#[localize("tests/locale/**/functions.ftl")]
pub enum MessageEnum {
    Length { items: Lines<String> },
    Numbers { items: Lines<String> },
    Plurals { items: Lines<String> },
}

#[localize("tests/locale/**/functions.ftl")]
pub struct Length {
    items: Lines<String>,
}

#[localize("tests/locale/**/functions.ftl")]
pub struct Numbers {
    items: Lines<String>,
}

#[localize("tests/locale/**/functions.ftl")]
pub struct Plurals {
    items: Lines<String>,
}

#[rstest]
#[case::zero(0)]
#[case::one(1)]
#[case::two(2)]
fn len(#[case] item_count: usize) {
    let items: Vec<String> = (0..item_count)
        .map(|index| format!("Item {index}"))
        .collect();

    compare_message(
        MessageEnum::Length {
            items: Lines::new(items.clone()),
        },
        format!("Item count: {item_count}"),
        DEFAULT_LOCALE,
    );
    compare_message(
        Length {
            items: Lines::new(items),
        },
        format!("Item count: {item_count}"),
        DEFAULT_LOCALE,
    );
}

#[rstest]
#[case::zero(0, "No items")]
#[case::one(1, "One item")]
#[case::two(2, "2 items")]
fn numbers(#[case] item_count: usize, #[case] expected: &str) {
    let items: Vec<String> = (0..item_count)
        .map(|index| format!("Item {index}"))
        .collect();

    compare_message(
        MessageEnum::Numbers {
            items: Lines::new(items.clone()),
        },
        expected,
        DEFAULT_LOCALE,
    );
    compare_message(
        Numbers {
            items: Lines::new(items),
        },
        expected,
        DEFAULT_LOCALE,
    );
}

#[rstest]
#[case::zero(0, "0 items")]
#[case::one(1, "One item")]
#[case::two(2, "2 items")]
fn plurals(#[case] item_count: usize, #[case] expected: &str) {
    let items: Vec<String> = (0..item_count)
        .map(|index| format!("Item {index}"))
        .collect();

    compare_message(
        MessageEnum::Plurals {
            items: Lines::new(items.clone()),
        },
        expected,
        DEFAULT_LOCALE,
    );
    compare_message(
        Plurals {
            items: Lines::new(items),
        },
        expected,
        DEFAULT_LOCALE,
    );
}