Crate attrs

Source
Expand description

An ergonomic Parser for #[attributes], built on parser combinators.

let mut rename_all = None::<Casing>;
let mut untagged = false;
let mut deny_unknown_fields = false;
let mut path_to_serde: Path = parse_quote!(::serde);
let attrs: Vec<Attribute> = parse_quote! {
    #[serde(rename_all = "kebab-case", untagged)]
    #[serde(crate = "custom::path")]
};

Attrs::new()
    .once("rename_all", with::eq(set::from_str(&mut rename_all)))
    .once("untagged", set::flag(&mut untagged))
    .once("deny_unknown_fields", set::flag(&mut deny_unknown_fields))
    .once("crate", with::eq(on::parse_str(&mut path_to_serde)))
    .parse_attrs("serde", &attrs)?;

assert_eq!(rename_all, Some(Casing::Kebab));
assert!(untagged);
assert!(!deny_unknown_fields); // not encountered, so not set
assert_eq!(path_to_serde.to_token_stream().to_string(), "custom :: path");

§Guide

#[attributes] as they are used in the Rust compiler and in the wild tend to look like this:

  #[repr(align(128), C)]
//  ^^^^ ^^^^^ ^^^   ^
//  path  key (val)  bare key

  #[serde(rename_all = "kebab-case", untagged)]
// ^^^^^^ ^^^^^^^^^^   ^^^^^^^^^^^^  ^^^^^^^^
//  path     key     =      val      bare key

To use this library, create an Attrs, and register different keys, each with a parsing function.

This library provides many parsing functions, but there are four key kinds:

  • lit takes a literal like true or 100 from the input.
  • from_str takes a ".." string from the input, before trying to FromStr it into an object.
  • parse_str takes a ".." string from the input, before trying to syn::parse it into an object.
  • parse directly tries to syn::parse the input.

Every function takes an &mut reference to its destination, which will be filled in when the corresponding key is encountered. The on module acts on direct references, whereas the set module acts on Options, filling them with Some.

The main ways to separate a key from its value are provided as combinators in the with module:

You may choose to accept a key once or many times, and you can, of course, write your own parsing functions for whatever syntax you have in mind.

Modules§

flag
Create Parsers which set bools.
on
Create Parsers that write to &mut T when they parse.
parse
Straightforward parsing functions.
set
Create Parsers that write to &mut Option<T>.
with
Wrap parsing functions so that they are e.g preceded by = or surrounded by (..).

Structs§

Attrs
Ergonomic Parser for #[attributes].

Traits§

Lit
A value that can be parsed by this crate from a syn::Lit.
UnwrapIdent
Conversion to an Ident.