Skip to content

Instantly share code, notes, and snippets.

Created July 22, 2015 21:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anonymous/cbf5d3611ff4ae498800 to your computer and use it in GitHub Desktop.
Save anonymous/cbf5d3611ff4ae498800 to your computer and use it in GitHub Desktop.
Shared via Rust Playground
// switch to nightly and uncomment these for debugging
//#![feature(trace_macros)]
//trace_macros!(true);
/// Trick the macro parser into outputting an item without checking its syntax
macro_rules! as_item( ($i:item) => ($i) );
macro_rules! foo(
// first rule: define the invocation syntax and call myself again with some
// easily parseable parameters (notice everything is bracketed)
(
pub struct $name:ident $body:tt
) => (
foo!(parse [pub struct $name] [] $body);
);
// the following rules are all internal to the macro
// this is the base case: all struct members have been munched,
// so proceed to output
(parse $decl:tt [$($member:tt)*] {})
=> ( foo!(output $decl [$($member)*]); );
// parse one public struct member, then call myself to parse the rest
(parse $decl:tt [$($member:tt)*] { pub $name:ident: $typ:ty, $($t:tt)* })
=> ( foo!(parse $decl [$($member)* pub $name: $typ,] { $($t)* }); );
// parse one private struct member, then call myself to parse the rest
(parse $decl:tt [$($member:tt)*] { $name:ident: $typ:ty, $($t:tt)* })
=> ( foo!(parse $decl [$($member)* $name: $typ,] { $($t)* }); );
// output the finished struct
(output [$($decls:tt)*] [$($member:tt)*])
=> ( as_item!(#[derive(Debug)] $($decls)* { $($member)* }); );
);
foo! {
pub struct Foo {
pub bar: usize,
baz: isize, // <-- Suppose, this should be private.
}
}
fn main() {
println!("{:#?}", Foo { bar: 0, baz: 0 });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment