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}