Skip to main content

Crate rcman_derive

Crate rcman_derive 

Source
Expand description

Derive macros for rcman settings library.

This crate provides #[derive(SettingsSchema)] for automatically generating settings schema implementations from Rust structs and tagged enums. It translates strongly-typed native Rust definitions directly into runtime rcman::SettingMetadata, prevents bugs through compile-time semantic validation, and generates rich IDE documentation cards with zero runtime cost.

§Features

  • Native Type Binding: Automatically translates String, PathBuf, integers, floats, bool, and Vec<T> into their corresponding rcman::SettingType.
  • Rich IDE IntelliSense Cards: Generates clean Markdown documentation cards for rust-analyzer showing type, range, constraints, security, and custom metadata.
  • Compile-Time const Keys: Generates uppercase pub const key constants directly on derived types (e.g. ServerSettings::PORT = "network.port").
  • Tagged-Union enum Support: Merges variant sub-schemas and generates discriminant selector metadata on enums annotated with #[serde(tag = "...")].
  • Strict Verification: Prevents contradictory constraints at compile time (e.g. min > max or options on bool).
  • Dynamic UI Metadata: Every unknown attribute literal (e.g., label = "Server") is automatically injected into the schema as customizable metadata.
  • #[cfg] Forwarding: Safely obeys macro feature flags attached to struct fields.
  • Typed Accessors: Generates snapshot accessors on the schema struct and a <SchemaName>ManagerAccessors trait for typed manager access.
  • Strongly-Typed validate(&self): Generates zero-overhead native validation checking numeric ranges, regex patterns, allowed dropdown options, and nested schemas directly on Rust structs.

§Usage

use rcman::DeriveSettingsSchema as SettingsSchema;
use serde::{Serialize, Deserialize};

#[derive(SettingsSchema, Default, Serialize, Deserialize)]
#[schema(category = "network")] // Required: sets the root prefix for the UI
struct NetworkSettings {
    /// Port used for external API connections.
    #[setting(
        label = "Server Port",
        description = "TCP port number",
        min = 1024,
        max = 65535,
        rename = "server-auth-port"
    )]
    pub port: u16,

    #[setting(rename = "enable_tls")]
    pub tls: bool,

    #[setting(rename = "server-url")]
    pub url: String,
     
    pub roles: Vec<String>,
}

fn main() {
    // Compile-time generated constant with rich IDE doc card:
    assert_eq!(NetworkSettings::PORT, "network.server-auth-port");
}

§Attribute Reference

§Container Attributes (#[schema(...)])

Apply these directly to the struct.

AttributeDescriptionRequiredExample
categoryThe root grouping prefix used for all fields.Yes#[schema(category = "general")]

§Field Attributes (#[setting(...)])

Apply these to individual struct fields.

AttributeType MappingDescriptionExample
renameAllOverrides the field name when constructing the schema key (category.rename)#[setting(rename = "App-Theme")]
skipAllSilently ignores the field; it will not appear in the settings schema#[setting(skip)]
secretAllAsserts the field contains sensitive data, diverting it to the OS Keychain backing#[setting(secret)]
categoryAllOverrides the container category specifically for this single field#[setting(category = "overridden")]
nestedStructsExtracts the schema from an inner struct and flattens it upward#[setting(nested)]
minNumberSets a numeric minimum constraint (must be <= max)#[setting(min = 1.0)]
maxNumberSets a numeric maximum constraint (must be >= min)#[setting(max = 100.0)]
stepNumberDefines valid increment stepping#[setting(step = 5.0)]
patternTextEnforces standard Regex validation string#[setting(pattern = "^[a-z]+$")]
optionsText/NumEnforces strict dropdown alternatives mappings#[setting(options(("val", "Label")))]

§Dynamic Metadata

Any key = value assignment in #[setting(...)] that isn’t functionally reserved above is transparently forwarded into the resulting SettingMetadata map for your UI components to access dynamically.

use rcman::DeriveSettingsSchema as SettingsSchema;
use serde::{Serialize, Deserialize};

#[derive(SettingsSchema, Default, Serialize, Deserialize)]
#[schema(category = "network")]
struct ServerSettings {
    #[setting(
        min = 1024,                  // 1. Reserved constraint
        label = "Server Port",       // 2. -> .meta_str("label", "Server Port")
        order = 1,                   // 3. -> .meta_num("order", 1)
        advanced = false             // 4. -> .meta_bool("advanced", false)
    )]
    pub port: u16,
}

fn main() {}

§Panics

This macro performs completely safe compile-time error reporting (yielding syn::Error) returning targeted IDE-friendly error underlines instead of panicking. It blocks:

  • Setting min/max/step on non-numeric types (bool, Vec, String).
  • Setting pattern on non-Text types (bool, Vec, i32).
  • Unknown/Unsupported types missing #[setting(skip)] (e.g. Duration or HashMap) so that you never accidentally leak invalid config metadata to the UI.

Derive Macros§

SettingsSchema
Derive macro for generating SettingsSchema implementations. See the crate-level documentation for full attribute reference.