es_fluent_derive/lib.rs
1#![doc = include_str!("../README.md")]
2
3use proc_macro_error2::proc_macro_error;
4
5mod macros;
6
7/// Turns an enum or struct into a localizable message.
8///
9/// - **Enums**: Each variant becomes a message ID (e.g., `MyEnum::Variant` -> `my_enum-Variant`).
10/// - **Structs**: The struct itself becomes the message ID (e.g., `MyStruct` -> `my_struct`).
11/// - **Fields**: Fields are automatically exposed as arguments to the Fluent message.
12///
13/// # Example
14///
15/// ```ignore
16/// use es_fluent::EsFluent;
17///
18/// #[derive(EsFluent)]
19/// pub enum LoginError {
20/// InvalidPassword, // no params
21/// UserNotFound { username: String }, // exposed as $username in the ftl file
22/// Something(String, String, String), // exposed as $f1, $f2, $f3 in the ftl file
23/// }
24///
25/// #[derive(EsFluent)]
26/// pub struct UserProfile<'a> {
27/// pub name: &'a str, // exposed as $name in the ftl file
28/// pub gender: &'a str, // exposed as $gender in the ftl file
29/// }
30/// ```
31///
32/// # Field Attributes
33///
34/// - `#[fluent(choice)]`: Marks a field as a selector for Fluent's select expression.
35#[proc_macro_derive(EsFluent, attributes(fluent))]
36#[proc_macro_error]
37pub fn derive_es_fluent(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
38 macros::derive_es_fluent::from(input)
39}
40
41/// Generates variant enums for struct fields.
42///
43/// This is perfect for generating UI labels, placeholders, or descriptions for a form object.
44///
45/// # Example
46///
47/// ```ignore
48/// use es_fluent::EsFluentVariants;
49///
50/// #[derive(EsFluentVariants)]
51/// #[fluent_variants(keys = ["label", "description"])]
52/// pub struct LoginForm {
53/// pub username: String,
54/// pub password: String,
55/// }
56///
57/// // Generates enums -> keys:
58/// // LoginFormLabelVariants::{Variants} -> (login_form_label-{variant})
59/// // LoginFormDescriptionVariants::{Variants} -> (login_form_description-{variant})
60/// ```
61///
62/// # Container Attributes
63///
64/// - `#[fluent_variants(keys = ["label", "description"])]`: Specifies which key variants to generate.
65#[proc_macro_derive(EsFluentVariants, attributes(fluent_variants))]
66#[proc_macro_error]
67pub fn derive_es_fluent_variants(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
68 macros::derive_es_fluent_variants::from(input)
69}
70
71/// Allows an enum to be used inside another message as a selector (e.g., for gender or status).
72///
73/// # Example
74///
75/// ```ignore
76/// use es_fluent::{EsFluent, EsFluentChoice};
77///
78/// #[derive(EsFluent, EsFluentChoice)]
79/// #[fluent_choice(serialize_all = "snake_case")]
80/// pub enum Gender {
81/// Male,
82/// Female,
83/// Other,
84/// }
85///
86/// #[derive(EsFluent)]
87/// pub struct UserProfile<'a> {
88/// pub name: &'a str,
89/// #[fluent(choice)] // Matches $gender -> [male]...
90/// pub gender: &'a Gender,
91/// }
92/// ```
93///
94/// # Container Attributes
95///
96/// - `#[fluent_choice(serialize_all = "...")]`: Controls variant name serialization (e.g., `"snake_case"`).
97#[proc_macro_derive(EsFluentChoice, attributes(fluent_choice))]
98#[proc_macro_error]
99pub fn derive_fluent_choice(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
100 macros::derive_fluent_choice::from(input)
101}
102
103/// Generates a helper implementation of the `ThisFtl` trait and registers the type's name as a key.
104///
105/// This is similar to `EsFluentVariants` (which registers fields), but for the parent type itself.
106///
107/// # Example
108///
109/// ```ignore
110/// use es_fluent::EsFluentThis;
111///
112/// #[derive(EsFluentThis)]
113/// #[fluent_this(origin)]
114/// pub enum Gender {
115/// Male,
116/// Female,
117/// Other,
118/// }
119///
120/// // Generates key: (gender_this)
121/// // Usage: Gender::this_ftl()
122/// ```
123///
124/// # Attributes
125///
126/// - `#[fluent_this(origin)]`: Generates an implementation where `this_ftl()` returns the base key for the type.
127/// - `#[fluent_this(members)]`: Can be combined with `EsFluentVariants` derives to generate keys for the generated member enums.
128/// - `#[fluent_this(origin, members)]`: Combines both behaviors.
129#[proc_macro_derive(EsFluentThis, attributes(fluent_this))]
130#[proc_macro_error]
131pub fn derive_es_fluent_this(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
132 macros::derive_es_fluent_this::from(input)
133}