kstool-helper-generator 0.7.1

A macro help user create mpsc communications and other
Documentation
mod basic;
mod bit;
mod enchanted;

/// Derive macro that generates an MPSC channel helper struct for an enum.
///
/// The enum name must contain "Event" (e.g., `MyEvent`). The macro generates:
/// - A helper struct named `{Prefix}Helper` (e.g., `MyHelper` from `MyEvent`)
/// - A receiver type alias named `{EnumName}Receiver`
/// - Async send methods for each enum variant (names converted to snake_case)
/// - A `new(size)` constructor returning `(Helper, Receiver)` tuple
/// - A `From<mpsc::Sender>` impl for the helper struct
///
/// # Attributes
///
/// - `#[helper(block)]` on the enum or variant: also generate blocking send methods (suffixed with `_b`)
/// - `#[helper(no_async)]` on the enum or variant: generate only blocking send methods (no async)
///
/// # Example
///
/// ```rust,ignore
/// #[derive(Helper)]
/// enum MyEvent {
///     UserLogin { username: String },
///     UserLogout,
///     DataUpdate(Vec<u8>),
/// }
/// // Generates: MyHelper with async methods user_login(), user_logout(), data_update()
/// ```
#[proc_macro_derive(Helper, attributes(helper))]
pub fn enum_helper_generator(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let st = syn::parse_macro_input!(input as syn::DeriveInput);
    //eprintln!("{:#?}", st.attrs);
    //eprintln!("{st:#?}");

    if let Err(e) = crate::basic::early_check(&st) {
        return e.into_compile_error().into();
    }

    basic::do_expand(&st, None)
        .unwrap_or_else(syn::Error::into_compile_error)
        .into()
}

/// Procedural macro that generates a bit flag enum with checker methods.
///
/// Each variant is assigned a unique power-of-two value (`1 << index`), and a
/// corresponding `is_{snake_case_name}()` method is generated on the enum.
///
/// The macro also derives `Clone`, `Copy`, and `Debug` for the generated enum.
///
/// # Example
///
/// ```rust,ignore
/// bit_helper! {
///     enum Features {
///         Analytics,      // = 1
///         Notifications,  // = 2
///         DarkMode,       // = 4
///     }
/// }
/// // Generates: Features with methods is_analytics(), is_notifications(), is_dark_mode()
/// ```
#[proc_macro]
pub fn bit_helper(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let st = syn::parse_macro_input!(input as syn::DeriveInput);
    //eprintln!("{:#?}", st.attrs);

    bit::parse_bit(st)
        .unwrap_or_else(|x| x.into_compile_error())
        .into()
}

/// Procedural macro that generates an MPSC helper with request-response support
/// via oneshot channels.
///
/// Similar to `#[derive(Helper)]`, but variants annotated with `#[ret(Type)]` will
/// have their generated methods return `Option<Type>` instead of `Option<()>`. The
/// macro automatically injects a `tokio::sync::oneshot::Sender` field into each
/// annotated variant and manages the oneshot channel lifecycle.
///
/// Variants without `#[ret(...)]` behave identically to the basic `Helper` derive.
///
/// The enum is re-emitted with the additional sender fields, so it must be used
/// as `oneshot_helper! { ... }` rather than as a derive macro.
///
/// # Example
///
/// ```rust,ignore
/// oneshot_helper! {
///     enum QueryEvent {
///         #[ret(String)]
///         GetConfig { key: String },
///         #[ret(bool)]
///         IsEnabled { feature: &'static str },
///         Shutdown,
///     }
/// }
/// // Generates: QueryHelper with methods:
/// //   async fn get_config(&self, key: String) -> Option<String>
/// //   async fn is_enabled(&self, feature: &'static str) -> Option<bool>
/// //   async fn shutdown(&self) -> Option<()>
/// ```
#[proc_macro]
pub fn oneshot_helper(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let early_st = syn::parse_macro_input!(input as syn::DeriveInput);
    enchanted::handle_new(early_st)
        .unwrap_or_else(syn::Error::into_compile_error)
        .into()
}