Crate attribute_derive
source ·Expand description
Basicly clap for attribute macros:
#[derive(Attribute)]
#[attribute(ident = collection)]
#[attribute(error(missing_field = "`{field}` was not specified"))]
struct CollectionAttribute {
// Options are optional by default (will be set to None if not specified)
authority: Option<String>,
name: String,
// Any type implementing default can be flagged as default
// This will be set to Vec::default() when not specified
#[attribute(optional)]
views: Vec<Type>,
// Booleans can be used without assiging a value. as a flag.
// If omitted they are set to false
some_flag: bool,
}
Will be able to parse an attribute like this:
#[collection(authority="Some String", name = r#"Another string"#, views = [Option, ()])]
Any type that ConvertParsed
is implemented for is 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
using Array
with the syntax [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
.
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 on
lists i
formatting. See interpolator docs for details.
Struct
-
ident = <ident>
The attribute ident. Improves error messages and enables thefrom_attributes
andremove_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. Supports{found_field}
and{expected_fields:i}
placeholders.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. Supports{found_field}
and{expected_field}
placeholders.unknown_field_empty = "expected empty attribute",
Custom error message printed if a property is specified, and attribute has no fields. Supports{found_field}
placeholder.duplicate_field = "`{field}` is specified multiple times",
Custom error message printed if a property is specified multiple times. Supports{field}
placeholder.missing_field = "required `{field}` is not specified",
Custom error message printed if a required property is not specified. Supports{field}
placeholder.field_help = "try `#[{attribute}({field}={example})]`",
Additional help message printed if a required property is not specified or has an error. Supports{attribute}
,{field}
and{example}
placeholder.missing_flag = "required `{flag}` is not specified",
Custom error message printed if a required flag is not specified. Supports{flag}
placeholder.flag_help = "try `#[{attribute}({flag})]`",
Additional help message printed if a required flag is not specified. Supports{attribute}
and{flag}
placeholder.conflict = "`{first}` conflicts with mutually exclusive `{second}`"
Custom error message printed if conflicting properties are specified. Supports{first}
and{second}
placeholder.
)
Fields
optional
/optional = true
If field is not specified, the default value is used instead.optional = false
Disables implicit optionality ofOption
,Vec
andbool
. Note that this makesOption<T>
behave the same asT
and makes a bool a mandatory flag.default = <default expr>
provides a default to be used instead ofDefault
. Enablesoptional
.conflicts = [<field>, ...]
Conflicting fieldsexample = "<example>"
Limitations
There are some limitations in syntax parsing that will be lifted in future releases.
- literals in top level (meaning something like
#[attr(42, 3.14, "hi")]
- function like arguments (something like
#[attr(view(a = "test"))]
- other syntaxes, maybe something like
key: value
Parse methods
There are multiple ways of parsing a struct deriving Attribute
.
For helper attributes there is:
Attribute::from_attributes
which takes in anIntoIterator<Item = &'a syn::Attribute
(e.g. a&Vec<syn::Attribute>
). Most useful for derive macros.Attribute::remove_attributes
which takes an&mut Vec<syn::Attribute>
and does not only parse theAttribute
but also removes those matching. Useful for helper attributes for proc macros, where the helper attributes need to be removed.
For parsing a single TokenStream
e.g. for parsing the proc macro input
there a two ways:
Attribute::from_args
taking in aTokenStream
- As
derive(Attribute)
also derivesParse
so you can use the parse API, e.g. withparse_macro_input!(tokens as Attribute)
.
Structs
- Helper struct to parse array literals:
[a, b, c]
- Helper struct to hold a value and the ident of its property
Traits
- The trait you actually derive on your attribute struct.
- Helper trait providing the path for an attribute.
- Helper trait to generate sensible errors
- Trait to join two structs of the same type