Expand description
Basically clap for attribute macros:
use attribute_derive::FromAttr;
#[derive(FromAttr)]
#[from_attr(ident = attr_name)]
// overriding the builtin error messages
#[from_attr(error(missing_field = "`{field}` was not specified"))]
struct MyAttribute {
// Positional values need to be specified before any named ones
#[from_attr(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
#[from_attr(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 syn::{Attribute, parse_quote};
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 thefrom_attributesandremove_attributesfunctions. -
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
optionalIf field is not specified, the default value is used instead.default = <default expr>provides a default to be used instead ofDefault::default(). Enablesoptional.conflicts(<field>, ...)Conflicting fieldsexample = "<example>"
§Parse methods
There are multiple ways of parsing a struct deriving FromAttr.
For helper attributes there is:
FromAttr::from_attributeswhich takes in anIntoIterator<Item = &'a syn::Attribute(e.g. a&Vec<syn::Attribute>). Most useful for derive macros.FromAttr::remove_attributeswhich takes a&mut Vec<syn::Attribute>and does not only parse the attributes, but also removes those matching. Useful for helper attributes for attribute macros, where the helper attributes need to be removed.
For parsing a single TokenStream e.g. for parsing the proc macro input
there are two ways:
FromAttr::from_argstaking in aTokenStream- As
derive(FromAttr)also derivesParseso you can use the parse API, e.g. withparse_macro_input!(tokens as Attribute).
Re-exports§
pub use utils::FlagOrValue;pub use from_partial::FromPartial;
Modules§
- from_
partial - Contains utilities for implementing
FromPartial. - parsing
- This module defines the traits defining how parsing works.
- utils
- Utilities implementing useful patterns for fields inside an attribute.
Macros§
- impl_
Attribute_ for_ Parse_ and_ ToTokens - Macro to easily implement
AttributeValuefor types implementingParseand [ToTokens].
Traits§
- Attribute
Ident - Helper trait providing the path for an attribute.
- From
Attr - The trait you actually derive on your attribute struct.