Git Product home page Git Product logo

darling's Introduction

Darling

Build Status Latest Version Rustc Version 1.31+

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.

Benefits

  • Easy and declarative parsing of macro input - make your proc-macros highly controllable with minimal time investment.
  • 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.

Usage

darling provides a set of traits which can be derived or manually implemented.

  1. 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.
  2. 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.
  3. 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.
  4. 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.

Additional Modules

  • darling::ast provides generic types for representing the AST.
  • darling::usage provides traits and functions for determining where type parameters and lifetimes are used in a struct or enum.
  • darling::util provides helper types with special FromMeta implementations, such as IdentList.

Example

#[macro_use]
extern crate darling;
extern crate syn;

#[derive(Default, FromMeta)]
#[darling(default)]
pub struct Lorem {
    #[darling(rename = "sit")]
    ipsum: bool,
    dolor: Option<String>,
}

#[derive(FromDeriveInput)]
#[darling(from_ident, attributes(my_crate), forward_attrs(allow, doc, cfg))]
pub struct MyTraitOpts {
    ident: syn::Ident,
    attrs: Vec<syn::Attribute>,
    lorem: Lorem,
}

The above code will then be able to parse this input:

/// A doc comment which will be available in `MyTraitOpts::attrs`.
#[derive(MyTrait)]
#[my_crate(lorem(dolor = "Hello", ipsum))]
pub struct ConsumingType;

Attribute Macros

Non-derive attribute macros are supported. To parse arguments for attribute macros, derive FromMeta on the argument receiver type, then pass &syn::AttributeArgs to the from_list method. This will produce a normal darling::Result<T> that can be used the same as a result from parsing a DeriveInput.

Macro Code

use darling::FromMeta;
use syn::{AttributeArgs, ItemFn};
use proc_macro::TokenStream;

#[derive(Debug, FromMeta)]
pub struct MacroArgs {
    #[darling(default)]
    timeout_ms: Option<u16>,
    path: String,
}

#[proc_macro_attribute]
fn your_attr(args: TokenStream, input: TokenStream) -> TokenStream {
    let attr_args = parse_macro_input!(args as AttributeArgs);
    let _input = parse_macro_input!(input as ItemFn);

    let _args = match MacroArgs::from_list(&attr_args) {
        Ok(v) => v,
        Err(e) => { return e.write_errors(); }
    };

    // do things with `args`
    unimplemented!()
}

Consuming Code

use your_crate::your_attr;

#[your_attr(path = "hello", timeout_ms = 15)]
fn do_stuff() {
    println!("Hello");
}

Features

Darling's features are built to work well for real-world projects.

  • Defaults: Supports struct- and field-level defaults, using the same path syntax as serde.
  • Field Renaming: Fields can have different names in usage vs. the backing code.
  • 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.
  • Mapping function: Use #[darling(map="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.
  • Skip fields: Use #[darling(skip)] to mark a field that shouldn't be read from attribute meta-items.
  • 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.
  • 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.
  • "Did you mean" suggestions: Compile errors from derived darling trait impls include suggestions for misspelled fields.

darling's People

Contributors

eijebong avatar hcpl avatar ignatenkobrain avatar kdy1 avatar teddriggs avatar upsuper avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.