1# Darling 2 3[](https://github.com/TedDriggs/darling/actions) 4[](https://crates.io/crates/darling) 5 6 7`darling` is a crate for proc macro authors, which enables parsing attributes into structs. It is heavily inspired by `serde` both in its internals and in its API. 8 9# Benefits 10 11- Easy and declarative parsing of macro input - make your proc-macros highly controllable with minimal time investment. 12- Great validation and errors, no work required. When users of your proc-macro make a mistake, `darling` makes sure they get error markers at the right place in their source, and provides "did you mean" suggestions for misspelled fields. 13 14# Usage 15 16`darling` provides a set of traits which can be derived or manually implemented. 17 181. `FromMeta` is used to extract values from a meta-item in an attribute. Implementations are likely reusable for many libraries, much like `FromStr` or `serde::Deserialize`. Trait implementations are provided for primitives, some std types, and some `syn` types. 192. `FromDeriveInput` is implemented or derived by each proc-macro crate which depends on `darling`. This is the root for input parsing; it gets access to the identity, generics, and visibility of the target type, and can specify which attribute names should be parsed or forwarded from the input AST. 203. `FromField` is implemented or derived by each proc-macro crate which depends on `darling`. Structs deriving this trait will get access to the identity (if it exists), type, and visibility of the field. 214. `FromVariant` is implemented or derived by each proc-macro crate which depends on `darling`. Structs deriving this trait will get access to the identity and contents of the variant, which can be transformed the same as any other `darling` input. 225. `FromAttributes` is a lower-level version of the more-specific `FromDeriveInput`, `FromField`, and `FromVariant` traits. Structs deriving this trait get a meta-item extractor and error collection which works for any syntax element, including traits, trait items, and functions. This is useful for non-derive proc macros. 23 24## Additional Modules 25 26- `darling::ast` provides generic types for representing the AST. 27- `darling::usage` provides traits and functions for determining where type parameters and lifetimes are used in a struct or enum. 28- `darling::util` provides helper types with special `FromMeta` implementations, such as `PathList`. 29 30# Example 31 32```rust,ignore 33use darling::{FromDeriveInput, FromMeta}; 34 35#[derive(Default, FromMeta)] 36#[darling(default)] 37pub struct Lorem { 38 #[darling(rename = "sit")] 39 ipsum: bool, 40 dolor: Option<String>, 41} 42 43#[derive(FromDeriveInput)] 44#[darling(attributes(my_crate), forward_attrs(allow, doc, cfg))] 45pub struct MyTraitOpts { 46 ident: syn::Ident, 47 attrs: Vec<syn::Attribute>, 48 lorem: Lorem, 49} 50``` 51 52The above code will then be able to parse this input: 53 54```rust,ignore 55/// A doc comment which will be available in `MyTraitOpts::attrs`. 56#[derive(MyTrait)] 57#[my_crate(lorem(dolor = "Hello", sit))] 58pub struct ConsumingType; 59``` 60 61# Attribute Macros 62 63Non-derive attribute macros are supported. 64To parse arguments for attribute macros, derive `FromMeta` on the argument receiver type, then use `darling::ast::NestedMeta::parse_meta_list` to convert the arguments `TokenStream` to a `Vec<NestedMeta>`, then pass that to the derived `from_list` method on your argument receiver type. 65This will produce a normal `darling::Result<T>` that can be used the same as a result from parsing a `DeriveInput`. 66 67## Macro Code 68 69```rust,ignore 70use darling::{Error, FromMeta}; 71use darling::ast::NestedMeta; 72use syn::ItemFn; 73use proc_macro::TokenStream; 74 75#[derive(Debug, FromMeta)] 76struct MacroArgs { 77 #[darling(default)] 78 timeout_ms: Option<u16>, 79 path: String, 80} 81 82#[proc_macro_attribute] 83pub fn your_attr(args: TokenStream, input: TokenStream) -> TokenStream { 84 let attr_args = match NestedMeta::parse_meta_list(args.into()) { 85 Ok(v) => v, 86 Err(e) => { return TokenStream::from(Error::from(e).write_errors()); } 87 }; 88 let _input = syn::parse_macro_input!(input as ItemFn); 89 90 let _args = match MacroArgs::from_list(&attr_args) { 91 Ok(v) => v, 92 Err(e) => { return TokenStream::from(e.write_errors()); } 93 }; 94 95 // do things with `args` 96 unimplemented!() 97} 98``` 99 100## Consuming Code 101 102```rust,ignore 103use your_crate::your_attr; 104 105#[your_attr(path = "hello", timeout_ms = 15)] 106fn do_stuff() { 107 println!("Hello"); 108} 109``` 110 111# Features 112 113Darling's features are built to work well for real-world projects. 114 115- **Defaults**: Supports struct- and field-level defaults, using the same path syntax as `serde`. 116 Additionally, `Option<T>` and `darling::util::Flag` fields are innately optional; you don't need to declare `#[darling(default)]` for those. 117- **Field Renaming**: Fields can have different names in usage vs. the backing code. 118- **Auto-populated fields**: Structs deriving `FromDeriveInput` and `FromField` can declare properties named `ident`, `vis`, `ty`, `attrs`, and `generics` to automatically get copies of the matching values from the input AST. `FromDeriveInput` additionally exposes `data` to get access to the body of the deriving type, and `FromVariant` exposes `fields`. 119 - **Transformation of forwarded attributes**: You can add `#[darling(with=path)]` to the `attrs` field to use a custom function to transform the forwarded attributes before they're provided to your struct. The function signature is `fn(Vec<Attribute>) -> darling::Result<T>`, where `T` is the type you declared for the `attrs` field. Returning an error from this function will propagate with all other parsing errors. 120- **Mapping function**: Use `#[darling(map="path")]` or `#[darling(and_then="path")]` to specify a function that runs on the result of parsing a meta-item field. This can change the return type, which enables you to parse to an intermediate form and convert that to the type you need in your struct. 121- **Skip fields**: Use `#[darling(skip)]` to mark a field that shouldn't be read from attribute meta-items. 122- **Multiple-occurrence fields**: Use `#[darling(multiple)]` on a `Vec` field to allow that field to appear multiple times in the meta-item. Each occurrence will be pushed into the `Vec`. 123- **Span access**: Use `darling::util::SpannedValue` in a struct to get access to that meta item's source code span. This can be used to emit warnings that point at a specific field from your proc macro. In addition, you can use `darling::Error::write_errors` to automatically get precise error location details in most cases. 124- **"Did you mean" suggestions**: Compile errors from derived darling trait impls include suggestions for misspelled fields. 125- **Struct flattening**: Use `#[darling(flatten)]` to remove one level of structure when presenting your meta item to users. Fields that are not known to the parent struct will be forwarded to the `flatten` field. 126 127## Shape Validation 128 129Some proc-macros only work on structs, while others need enums whose variants are either unit or newtype variants. 130Darling makes this sort of validation extremely simple. 131On the receiver that derives `FromDeriveInput`, add `#[darling(supports(...))]` and then list the shapes that your macro should accept. 132 133| Name | Description | 134| ---------------- | ------------------------------------------------------------------------- | 135| `any` | Accept anything | 136| `struct_any` | Accept any struct | 137| `struct_named` | Accept structs with named fields, e.g. `struct Example { field: String }` | 138| `struct_newtype` | Accept newtype structs, e.g. `struct Example(String)` | 139| `struct_tuple` | Accept tuple structs, e.g. `struct Example(String, String)` | 140| `struct_unit` | Accept unit structs, e.g. `struct Example;` | 141| `enum_any` | Accept any enum | 142| `enum_named` | Accept enum variants with named fields | 143| `enum_newtype` | Accept newtype enum variants | 144| `enum_tuple` | Accept tuple enum variants | 145| `enum_unit` | Accept unit enum variants | 146 147Each one is additive, so listing `#[darling(supports(struct_any, enum_newtype))]` would accept all structs and any enum where every variant is a newtype variant. 148 149This can also be used when deriving `FromVariant`, without the `enum_` prefix. 150