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