Crate attribute_derive

source ·
Expand description

Basically clap for attribute macros:

use attribute_derive::FromAttr;
#[derive(FromAttr)]
#[attribute(ident = attr_name)]
// overriding the builtin error messages
#[attribute(error(missing_field = "`{field}` was not specified"))]
struct MyAttribute {
    // Positional values need to be specified before any named ones
    #[attribute(positional)]
    positional: u8,
    // Options are optional by default (will be set to None if not specified)
    optional: Option<String>,
    required: String,
    // Any type implementing default can be flagged as default
    // This will be set to Vec::default() when not specified
    #[attribute(optional)]
    list: Vec<syn::Type>,
    // Booleans can be used without assigning a value, i.e., as a flag.
    // If omitted they are set to false
    some_flag: bool,
}

Will be able to parse an attribute like this:

#[attr_name(5, optional="some", required = r#"string"#, some_flag, list = [Option, ()])]
// or
#[attr_name(5, required = "string", list(Option, ()))]

Any type that for AttributeNamed or AttributePositional are implemented respectively are supported. These should be the general types that syn supports like LitStr or Type or that have a direct equivalent in those like String, char or f32. A special treatment have Vecs which are parsed as either name = [a, b, c] or name(a, b, c) and Options that will be None if not specified and Some when the value is specified via the attribute. It is not specified via Some(value) but as just value. Bools are used for flags, i.e., without a value. Most should just behave as expected, see parsing for details.

Tuple structs can derive FromAttr as well, but all fields will be positional. Tuples with a single field (new types) will copy the behavior of the contained field, e.g. for bool:

use attribute_derive::FromAttr;

#[derive(FromAttr, PartialEq, Debug)]    
#[attribute(ident = flag)]
struct Flag(bool);

let attr: Attribute = parse_quote!(#[flag]);
assert_eq!(Flag::from_attribute(attr).unwrap(), Flag(true));

let attr: Attribute = parse_quote!(#[flag = true]);
assert_eq!(Flag::from_attribute(attr).unwrap(), Flag(true));

let attr: Attribute = parse_quote!(#[flag(false)]);
assert_eq!(Flag::from_attribute(attr).unwrap(), Flag(false));

§Attributes

The parsing of attributes can be modified with the following parameters via the #[attribute(<params>)] attribute. All of them are optional. Error messages are formatted using interpolator, and only support display and lists i formatting. See interpolator docs for details.

§Struct

  • ident = <ident> The attribute ident. Improves error messages and enables the from_attributes and remove_attributes functions.

  • aliases = [<alias>, ...] Aliases for the attribute ident.

  • error = "<error message>" Overrides default error message.

  • error(

    • unknown_field = "supported fields are {expected_fields:i..-1(`{}`)(, )} and `{expected_fields:i-1}`", Custom error message printed if an unknown property is specified and attribute has more than one field. Placeholders: {expected_fields:i}.
    • unknown_field_single = "expected supported field `{expected_field}`", Custom error message printed if an unknown property is specified, and attribute only has a single field. Placeholders: {expected_field}.
    • unknown_field_empty = "expected empty attribute", Custom error message printed if a property is specified, and attribute has no fields.
    • duplicate_field = "`{field}` is specified multiple times", Custom error message printed if a property is specified multiple times. Placeholders: {field}.
    • missing_field = "required `{field}` is not specified", Custom error message printed if a required property is not specified. Placeholders: {field}.
    • field_help = "try `#[{attribute}({field}={example})]`", Additional help message printed if a required property is not specified or has an error. Placeholders: {attribute}, {field} and {example}.
    • conflict = "`{first}` conflicts with mutually exclusive `{second}`" Custom error message printed when conflicting properties are specified. Placeholders: {first} and {second}.

    )

§Fields

  • optional If field is not specified, the default value is used instead.
  • default = <default expr> provides a default to be used instead of Default::default(). Enables optional.
  • conflicts(<field>, ...) Conflicting fields
  • example = "<example>"

§Parse methods

There are multiple ways of parsing a struct deriving FromAttr.

For helper attributes there is:

For parsing a single TokenStream e.g. for parsing the proc macro input there are two ways:

Re-exports§

Modules§

  • Contains utilities for implementing FromPartial.
  • This module defines the traits defining how parsing works.
  • Utilities implementing useful patterns for fields inside an attribute.

Traits§

  • Helper trait providing the path for an attribute.
  • The trait you actually derive on your attribute struct.

Derive Macros§