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
//! Features a plugin supports. This is essentially the same thing as tags, keyword, or categories.
//! Hosts may use these to organize plugins.

/// A keyword for a CLAP plugin. See
/// <https://github.com/free-audio/clap/blob/main/include/clap/plugin-features.h> for more
/// information.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ClapFeature {
    // These are the main categories, every plugin should have at least one of these
    Instrument,
    AudioEffect,
    NoteDetector,
    NoteEffect,
    // These are optional
    Analyzer,
    Synthesizer,
    Sampler,
    Drum,
    DrumMachine,
    Filter,
    Phaser,
    Equalizer,
    Deesser,
    PhaseVocoder,
    Granular,
    FrequencyShifter,
    PitchShifter,
    Distortion,
    TransientShaper,
    Compressor,
    Expander,
    Gate,
    Limiter,
    Flanger,
    Chorus,
    Delay,
    Reverb,
    Tremolo,
    Glitch,
    Utility,
    PitchCorrection,
    Restoration,
    MultiEffects,
    Mixing,
    Mastering,
    Mono,
    Stereo,
    Surround,
    Ambisonic,
    /// A non-predefined feature. Hosts may display this among its plugin categories. Custom
    /// features _must_ be prefixed by a namespace in the format `namespace:feature_name`.
    Custom(&'static str),
}

impl ClapFeature {
    pub fn as_str(&self) -> &'static str {
        match self {
            ClapFeature::Instrument => "instrument",
            ClapFeature::AudioEffect => "audio-effect",
            ClapFeature::NoteDetector => "note-detector",
            ClapFeature::NoteEffect => "note-effect",
            ClapFeature::Analyzer => "analyzer",
            ClapFeature::Synthesizer => "synthesizer",
            ClapFeature::Sampler => "sampler",
            ClapFeature::Drum => "drum",
            ClapFeature::DrumMachine => "drum-machine",
            ClapFeature::Filter => "filter",
            ClapFeature::Phaser => "phaser",
            ClapFeature::Equalizer => "equalizer",
            ClapFeature::Deesser => "de-esser",
            ClapFeature::PhaseVocoder => "phase-vocoder",
            ClapFeature::Granular => "granular",
            ClapFeature::FrequencyShifter => "frequency-shifter",
            ClapFeature::PitchShifter => "pitch-shifter",
            ClapFeature::Distortion => "distortion",
            ClapFeature::TransientShaper => "transient-shaper",
            ClapFeature::Compressor => "compressor",
            ClapFeature::Expander => "expander",
            ClapFeature::Gate => "gate",
            ClapFeature::Limiter => "limiter",
            ClapFeature::Flanger => "flanger",
            ClapFeature::Chorus => "chorus",
            ClapFeature::Delay => "delay",
            ClapFeature::Reverb => "reverb",
            ClapFeature::Tremolo => "tremolo",
            ClapFeature::Glitch => "glitch",
            ClapFeature::Utility => "utility",
            ClapFeature::PitchCorrection => "pitch-correction",
            ClapFeature::Restoration => "restoration",
            ClapFeature::MultiEffects => "multi-effects",
            ClapFeature::Mixing => "mixing",
            ClapFeature::Mastering => "mastering",
            ClapFeature::Mono => "mono",
            ClapFeature::Stereo => "stereo",
            ClapFeature::Surround => "surround",
            ClapFeature::Ambisonic => "ambisonic",
            ClapFeature::Custom(s) => {
                // Custom features must be prefixed with a namespace. We'll use `.split(':').all()`
                // here instead of `.split_once()` in case the user for whatever reason uses more
                // than one colon (which the docs don't say anything about, but uh yeah).
                nih_debug_assert!(
                    s.contains(':') && s.split(':').all(|x| !x.is_empty()),
                    "'{s}' is not a valid feature, custom features must be namespaced (e.g. \
                     'nih:{s}')",
                    s = s
                );

                s
            }
        }
    }
}