#macro #parse #generics #where

parse-generics-shim

A stable shim for the proposed RFC #1583; provides macros for parsing generics and where clauses

2 releases

0.1.1 Jul 30, 2016
0.1.0 May 1, 2016

#1 in #generics

Download history 3/week @ 2018-09-03 2/week @ 2018-09-10 5/week @ 2018-09-17 6/week @ 2018-09-24 11/week @ 2018-10-01 5/week @ 2018-10-08 7/week @ 2018-10-15 10/week @ 2018-10-22 2/week @ 2018-10-29 11/week @ 2018-11-05 9/week @ 2018-11-12 7/week @ 2018-11-19 57/week @ 2018-11-26

53 downloads per month
Used in 9 crates (7 directly)

MIT/Apache

59KB
1K SLoC


lib.rs:

This crate provides stable, partial implementations of the parse_generics! and parse_where! macros proposed in RFC #1583. These macros serve two purposes:

  1. They allow crate authors to use the macros in a limited capacity whether or not the RFC is accepted.
  2. They demonstrate to the Rust core team that there is demand for this functionality.
  3. They provide a migration path from the partial implementation to the full one, assuming the RFC does get accepted.

Because these macros are implemented using macro_rules!, they have the following limitations:

  • In general, only lifetimes 'a through 'z are accepted.
  • Only a subset of the full output formats are supported.
  • They are significantly less efficient, and consume a non-trivial amount of the recursion limit.
<style type="text/css"> .link-block { font-family: "Fira Sans"; } .link-block > p { display: inline-block; } .link-block > p > strong { font-weight: 500; margin-right: 1em; } .link-block > ul { display: inline-block; padding: 0; list-style: none; } .link-block > ul > li { font-size: 0.8em; background-color: #eee; border: 1px solid #ccc; padding: 0.3em; display: inline-block; } </style>

Table of Contents

parse_generics_shim!

macro_rules! parse_generics_shim {
(
{ $($fields:ident),+ },
then $callback_name:ident ! ( $($callback_args:tt)* ),
$($code:tt)*
) => { ... };
}

Parses a generic parameter list (if present) from the start of $($code:tt)*, expanding to the parsed information plus the unconsumed tokens after the parameter list. The general form of the expansion is:

$callback_name! {
$($callback_args)*
{
$(
$fields: [ .. ],
)+
},
$($tail)*
}

Callback

$callback_name and $callback_args specify the macro to invoke with the result of parsing. Note that $callback_args may be contained in any of ( .. ), [ .. ], or { .. }.

Fields

$fields indicates which pieces of information you want in the expansion. The available fields are:

  • constr - comma-terminated list of generic parameters plus their constraints.
  • params - comma-terminated list of generic parameter names (both lifetimes and types).
  • ltimes - comma-terminated list of generic lifetime names.
  • tnames - comma-terminated list of generic type names.

The shim only supports the following combinations:

  • { constr, params, ltimes, tnames }
  • { constr }
  • { .. }

The fields will appear in the output in the same order they appear in the input. One special case is { .. } which causes all fields to be emitted, followed by a literal .. token.

Warning: there is explicitly no guarantee that the list of fields will stay the same over time. As such, it is strongly recommended that you never directly match the .. token after the fields. Instead, you should use the following construct:

macro_rules! match_output {
(
{
// Match the fields you care about.
constr: $constr:tt,
params: [ $($params:tt,)* ],

// Ignore the rest; *never* explicitly match `..`!
$($_fields:tt)*
},

$($tail:tt)*
) => { ... };
}

Code

$code is the actual source code to be parsed. If it starts with <, the macro will parse a generic parameter list. If it does not start with <, the macro will proceed as though the input started with an empty generic parameter list (i.e. <>).

Examples

The following show how the various invocation forms affect the output:

# #![cfg_attr(feature="use-parse-generics-poc", feature(plugin))]
# #![cfg_attr(feature="use-parse-generics-poc", plugin(parse_generics_poc))]
# #[macro_use] extern crate parse_generics_shim;
# fn main() {
# assert_eq!( (
parse_generics_shim! {
{ constr, params, ltimes, tnames },
then stringify!(output:),
<'a, T, U: 'a + Copy> X
}

// Expands to:
# /*
stringify!(
# 

Dependencies