wp_mini/field/
macros.rs

1//! Contains utility macros for the `field` module.
2//!
3//! These macros help reduce boilerplate code when implementing common traits
4//! for the various field enums.
5
6/// Implements `std::fmt::Display` for a field enum with complex (nested) variants.
7///
8/// This macro handles field enums that contain both simple variants (e.g., `Title`)
9/// and complex variants that hold a `Vec` of sub-fields (e.g., `User(Vec<UserField>)`).
10///
11/// - For simple variants, it relies on `strum`'s `AsRefStr` trait to produce the `camelCase` string.
12/// - For complex variants, it formats them as `fieldName(subField1,subField2,...)`.
13///
14/// # Arguments
15/// * `$enum_name:ident` - The name of the enum to implement `Display` for.
16/// * `$( $variant:ident => $name:literal ),*` - A comma-separated list of the complex variants.
17///   Each entry specifies the `VariantName` and the exact string literal to use for its name.
18///
19/// # Example
20/// ```
21///
22/// // An enum with simple and complex variants
23/// use wp_mini::impl_field_display;
24///
25/// #[derive(strum_macros::AsRefStr)]
26/// #[strum(serialize_all = "camelCase")]
27/// enum StoryField {
28///     Title,
29///     VoteCount,
30///     // A complex variant with sub-fields
31///     User(Vec<UserField>),
32/// }
33///
34/// #[derive(strum_macros::AsRefStr)]
35/// #[strum(serialize_all = "camelCase")]
36/// enum UserField {
37///     Username,
38///     Avatar,
39/// }
40///
41/// // Generate the Display implementation using the macro
42/// impl_field_display!(StoryField, User => "user");
43///
44/// // --- Verification ---
45/// // Simple field
46/// let simple_field = StoryField::VoteCount;
47/// assert_eq!(simple_field.to_string(), "voteCount");
48///
49/// // Complex field
50/// let complex_field = StoryField::User(vec![UserField::Username, UserField::Avatar]);
51/// assert_eq!(complex_field.to_string(), "user(username,avatar)");
52/// ```
53#[macro_export]
54macro_rules! impl_field_display {
55    // Top-level entry point for the macro.
56    // It takes the enum name and a comma-separated list of complex variants.
57    // Each complex variant is specified as `VariantName => "string_to_use"`.
58    ($enum_name:ident, $( $variant:ident => $name:literal ),* ) => {
59        impl std::fmt::Display for $enum_name {
60            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61                match self {
62                    // This part iterates through each `Variant => "name"` pair provided.
63                    $(
64                        // For each pair, it generates a match arm.
65                        $enum_name::$variant(sub_fields) => {
66                            // This logic is the same as your original implementation.
67                            let sub_fields_str = sub_fields
68                                .iter()
69                                .map(|field| field.to_string())
70                                .collect::<Vec<String>>()
71                                .join(",");
72                            // It writes the specified string name, not the variant name.
73                            write!(f, "{}({})", $name, sub_fields_str)
74                        },
75                    )*
76
77                    // The fallback arm for all simple variants remains the same.
78                    // It relies on the `AsRefStr` derive from the `strum` crate.
79                    _ => write!(f, "{}", self.as_ref()),
80                }
81            }
82        }
83    };
84}