Skip to main content

Attribute

Derive Macro Attribute 

Source
#[derive(Attribute)]
{
    // Attributes available to this derive:
    #[zyn]
}
Expand description

Derives typed attribute parsing from #[attr(...)] key-value syntax.

Attribute mode (#[zyn("name")]): also implements FromInput so the struct can be used as an Attr<T> extractor in #[element] or #[derive].

Argument mode (no #[zyn("name")]): implements FromArgs and FromArg only, suitable for nested argument structures.

§Field options

AttributeEffect
#[zyn(default)]Uses Default::default() when the field is absent
#[zyn(default = "val")]Uses Into::into("val") as the default
#[zyn(about = "...")]Doc string shown in about() output

§Examples

Attribute mode (registers FromInput + FromArgs):

#[derive(zyn::Attribute)]
#[zyn("my_attr", about = "controls behaviour")]
struct MyAttr {
    #[zyn(about = "the item name")]
    rename: Option<String>,
    #[zyn(default)]
    skip: bool,
}

// Used as an extractor in an element:
#[zyn::element]
fn my_element(#[zyn(input)] attr: zyn::Attr<MyAttr>) -> zyn::TokenStream {
    zyn::zyn!(@if (attr.skip) { /* nothing */ } @else { /* generate */ })
}

// Applied to a type:
#[my_attr(rename = "other_name")]
struct Foo;

Argument mode (no #[zyn("name")]):

#[derive(zyn::Attribute)]
struct Config { level: i64, tag: String }

let args: zyn::Args = zyn::parse!("level = 3, tag = \"v1\"").unwrap();
let cfg = Config::from_args(&args).unwrap();

§Diagnostics

Errors are accumulated and returned together. Unknown arguments automatically produce “did you mean?” suggestions when a close match exists:

#[derive(zyn::Attribute)]
#[zyn("config")]
struct Config {
    enabled: bool,
    format: String,
}

// #[config(enabed, fromat = "json")]
//
// error: unknown argument `enabed`
//   --> src/lib.rs:10:10
//    |
// 10 | #[config(enabed, fromat = "json")]
//    |          ^^^^^^
//    |
//    = help: did you mean `enabled`?
//
// error: unknown argument `fromat`
//   --> src/lib.rs:10:18
//    |
// 10 | #[config(enabed, fromat = "json")]
//    |                  ^^^^^^
//    |
//    = help: did you mean `format`?

Enum derive for variant dispatch:

#[derive(zyn::Attribute)]
enum Mode {
    Fast,
    Slow,
    Custom { speed: i64 },
}

let arg: zyn::Arg = zyn::parse!("custom(speed = 10)").unwrap();
let mode = Mode::from_arg(&arg).unwrap();
// mode == Mode::Custom { speed: 10 }