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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//! Derive macros for the Beamer VST3 framework.
//!
//! This crate provides the `#[derive(Params)]` macro for generating parameter
//! trait implementations automatically.
//!
//! # Declarative Parameter Definition
//!
//! Parameters can be defined entirely through attributes - the macro generates
//! the `Default` impl automatically:
//!
//! ```ignore
//! use beamer::prelude::*;
//!
//! #[derive(Params)]
//! pub struct GainParams {
//! #[param(id = "gain", name = "Gain", default = 0.0, range = -60.0..=12.0, kind = "db")]
//! pub gain: FloatParam,
//!
//! #[param(id = "bypass", bypass = true)]
//! pub bypass: BoolParam,
//! }
//!
//! // No manual Default impl needed - macro generates everything!
//! ```
//!
//! The macro generates implementations for both `Params` (new system) and
//! `Parameters` (VST3 integration) traits, plus `Default` when all required
//! attributes are present.
//!
//! # Flat Visual Grouping
//!
//! Use `group = "..."` for visual grouping in the DAW without nested structs:
//!
//! ```ignore
//! #[derive(Params)]
//! pub struct SynthParams {
//! // Filter parameters - grouped visually in DAW
//! #[param(id = "cutoff", name = "Cutoff", group = "Filter", ...)]
//! pub cutoff: FloatParam,
//!
//! #[param(id = "reso", name = "Resonance", group = "Filter", ...)]
//! pub resonance: FloatParam,
//!
//! // Output parameters - different visual group
//! #[param(id = "gain", name = "Gain", group = "Output", ...)]
//! pub gain: FloatParam,
//! }
//!
//! // Access is flat: params.cutoff, params.resonance, params.gain
//! // But DAW shows them in collapsible "Filter" and "Output" groups
//! ```
use TokenStream;
/// Derive macro for implementing parameter traits.
///
/// This macro generates:
/// - `Params` trait implementation (count, iter, by_id, save_state, load_state)
/// - `Parameters` trait implementation (VST3 integration)
/// - `Default` implementation (when declarative attributes are complete)
/// - Compile-time hash collision detection
///
/// # Attributes
///
/// ## Required
/// - `id = "..."` - String ID that gets hashed to u32 for VST3.
///
/// ## Declarative (enables auto-generated Default)
/// - `name = "..."` - Display name
/// - `default = <value>` - Default value (float, int, or bool)
/// - `range = start..=end` - Value range (for FloatParam/IntParam)
/// - `kind = "..."` - Unit type: db, hz, ms, seconds, percent, pan, ratio, linear, semitones
/// - `short_name = "..."` - Short name for constrained UIs
/// - `smoothing = "exp:5.0"` - Parameter smoothing (exp or linear)
/// - `bypass` - Mark as bypass parameter (BoolParam only)
/// - `group = "..."` - Visual grouping in DAW without nested struct
///
/// ## Nested Groups
/// - `#[nested(group = "...")]` - For fields containing nested parameter structs
///
/// # Example
///
/// ```ignore
/// #[derive(Params)]
/// pub struct PluginParams {
/// #[param(id = "gain", name = "Gain", default = 0.0, range = -60.0..=12.0, kind = "db")]
/// pub gain: FloatParam,
///
/// #[param(id = "freq", name = "Frequency", default = 1000.0, range = 20.0..=20000.0, kind = "hz", group = "Filter")]
/// pub frequency: FloatParam,
///
/// #[nested(group = "Output")]
/// pub output: OutputParams,
/// }
/// ```
/// Derive macro for implementing `EnumParamValue` trait on enums.
///
/// This macro generates the `EnumParamValue` implementation that allows
/// an enum to be used with `EnumParam<E>` in parameter structs.
///
/// # Requirements
///
/// - The type must be an enum
/// - All variants must be unit variants (no fields)
/// - The enum must also derive `Copy`, `Clone`, and `PartialEq`
///
/// # Attributes
///
/// - `#[name = "..."]` - Optional display name for a variant. If not specified,
/// the variant identifier is used as the display name.
/// - `#[default]` - Mark a variant as the default. If not specified, the first
/// variant is used. Only one variant can be marked as default.
///
/// # Example
///
/// ```ignore
/// use beamer::EnumParam;
///
/// #[derive(Copy, Clone, PartialEq, EnumParam)]
/// pub enum FilterType {
/// #[name = "Low Pass"]
/// LowPass,
/// #[default]
/// #[name = "High Pass"]
/// HighPass,
/// #[name = "Band Pass"]
/// BandPass,
/// Notch, // Uses "Notch" as display name
/// }
///
/// // Now FilterType can be used with EnumParam:
/// #[derive(Params)]
/// pub struct FilterParams {
/// #[param(id = "filter_type")]
/// pub filter_type: EnumParam<FilterType>,
/// }
/// ```