Skip to main content

wavecraft_macros/
lib.rs

1//! Wavecraft procedural macros for plugin development.
2//!
3//! This crate provides derive macros and procedural macros that simplify
4//! audio plugin creation by automatically generating boilerplate code.
5
6extern crate proc_macro;
7
8mod plugin;
9mod processor_params;
10
11use proc_macro::TokenStream;
12
13/// Derive macro for implementing `ProcessorParams` trait.
14///
15/// This macro automatically generates parameter metadata from struct fields
16/// annotated with `#[param(...)]` attributes.
17///
18/// # Example
19///
20/// ```text
21/// use wavecraft_macros::ProcessorParams;
22///
23/// #[derive(ProcessorParams, Default)]
24/// struct GainParams {
25///     #[param(range = "0.0..=2.0", default = 1.0, unit = "x")]
26///     level: f32,
27/// }
28/// ```
29#[proc_macro_derive(ProcessorParams, attributes(param))]
30pub fn derive_processor_params(input: TokenStream) -> TokenStream {
31    processor_params::derive(input)
32}
33
34/// Procedural macro for generating complete plugin implementations.
35///
36/// This macro parses a minimal DSL and generates all the boilerplate code for
37/// a working VST3/CLAP plugin. Plugin metadata is automatically derived from
38/// your `Cargo.toml`.
39///
40/// # Syntax (0.9.0+)
41///
42/// ```text
43/// use wavecraft::prelude::*;
44///
45/// // Define your processor wrapper
46/// wavecraft_processor!(MyGain => Gain);
47///
48/// // Generate complete plugin with minimal boilerplate
49/// wavecraft_plugin! {
50///     name: "My Plugin",
51///     signal: SignalChain![MyGain],
52/// }
53/// ```
54///
55/// # Metadata Derivation
56///
57/// The macro automatically derives plugin metadata from `Cargo.toml`:
58/// - **Vendor**: First author in `authors` field (or "Unknown")
59/// - **URL**: `homepage` field (or `repository` if homepage empty)
60/// - **Email**: Extracted from first author's email in `authors` field
61/// - **Version**: `version` field (via `CARGO_PKG_VERSION`)
62///
63/// Add metadata to your `Cargo.toml`:
64///
65/// ```toml
66/// [package]
67/// authors = ["Your Name <your.email@example.com>"]
68/// homepage = "https://yourproject.com"
69/// ```
70///
71/// # Optional `crate` Property
72///
73/// If you've renamed the `wavecraft` dependency in your `Cargo.toml`:
74///
75/// ```toml
76/// [dependencies]
77/// my_wavecraft = { package = "wavecraft-nih_plug", ... }
78/// ```
79///
80/// Then specify the renamed crate:
81///
82/// ```text
83/// wavecraft_plugin! {
84///     name: "My Plugin",
85///     signal: SignalChain![MyGain],
86///     crate: my_wavecraft,  // Optional
87/// }
88/// ```
89///
90/// # Breaking Changes (0.9.0)
91///
92/// - Removed `vendor`, `url`, `email` properties (now auto-derived)
93/// - Bare processors no longer accepted: use `SignalChain![...]` wrapper
94/// - VST3 Class IDs now use package name instead of vendor (plugins get new IDs)
95/// - Default `crate` path changed from `::wavecraft_nih_plug` to `::wavecraft`
96///
97/// See `docs/MIGRATION-0.9.md` for migration guide.
98///
99/// # Known Limitations
100///
101/// **Parameter Automation**: The DSL-generated `process()` method always receives
102/// default parameter values. Host automation and UI work correctly, but the
103/// `Processor` cannot read parameter changes.
104///
105/// **Workaround**: For parameter-driven DSP, implement the `Plugin` trait directly
106/// instead of using this macro. See SDK documentation for examples.
107///
108/// **Tracking**: This limitation is tracked in the SDK roadmap for future releases.
109#[proc_macro]
110pub fn wavecraft_plugin(input: TokenStream) -> TokenStream {
111    plugin::wavecraft_plugin_impl(input)
112}