• Stars
    star
    131
  • Rank 267,966 (Top 6 %)
  • Language
    Rust
  • License
    MIT License
  • Created over 7 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Utilities for dealing with substructures within syn macros

synstructure

Latest Version Documentation Build Status Rustc Version 1.31+

NOTE: What follows is an exerpt from the module level documentation. For full details read the docs on docs.rs

This crate provides helper types for matching against enum variants, and extracting bindings to each of the fields in the deriving Struct or Enum in a generic way.

If you are writing a #[derive] which needs to perform some operation on every field, then you have come to the right place!

Example: WalkFields

Trait Implementation

pub trait WalkFields: std::any::Any {
    fn walk_fields(&self, walk: &mut FnMut(&WalkFields));
}
impl WalkFields for i32 {
    fn walk_fields(&self, _walk: &mut FnMut(&WalkFields)) {}
}

Custom Derive

#[macro_use]
extern crate synstructure;
#[macro_use]
extern crate quote;
extern crate proc_macro2;

fn walkfields_derive(s: synstructure::Structure) -> proc_macro2::TokenStream {
    let body = s.each(|bi| quote!{
        walk(#bi)
    });

    s.bound_impl(quote!(example_traits::WalkFields), quote!{
        fn walk_fields(&self, walk: &mut FnMut(&example_traits::WalkFields)) {
            match *self { #body }
        }
    })
}
decl_derive!([WalkFields] => walkfields_derive);

/*
 * Test Case
 */
fn main() {
    test_derive! {
        walkfields_derive {
            enum A<T> {
                B(i32, T),
                C(i32),
            }
        }
        expands to {
            #[allow(non_upper_case_globals)]
            const _DERIVE_example_traits_WalkFields_FOR_A: () = {
                extern crate example_traits;
                impl<T> example_traits::WalkFields for A<T>
                    where T: example_traits::WalkFields
                {
                    fn walk_fields(&self, walk: &mut FnMut(&example_traits::WalkFields)) {
                        match *self {
                            A::B(ref __binding_0, ref __binding_1,) => {
                                { walk(__binding_0) }
                                { walk(__binding_1) }
                            }
                            A::C(ref __binding_0,) => {
                                { walk(__binding_0) }
                            }
                        }
                    }
                }
            };
        }
    }
}

Example: Interest

Trait Implementation

pub trait Interest {
    fn interesting(&self) -> bool;
}
impl Interest for i32 {
    fn interesting(&self) -> bool { *self > 0 }
}

Custom Derive

#[macro_use]
extern crate synstructure;
#[macro_use]
extern crate quote;
extern crate proc_macro2;

fn interest_derive(mut s: synstructure::Structure) -> proc_macro2::TokenStream {
    let body = s.fold(false, |acc, bi| quote!{
        #acc || example_traits::Interest::interesting(#bi)
    });

    s.bound_impl(quote!(example_traits::Interest), quote!{
        fn interesting(&self) -> bool {
            match *self {
                #body
            }
        }
    })
}
decl_derive!([Interest] => interest_derive);

/*
 * Test Case
 */
fn main() {
    test_derive!{
        interest_derive {
            enum A<T> {
                B(i32, T),
                C(i32),
            }
        }
        expands to {
            #[allow(non_upper_case_globals)]
            const _DERIVE_example_traits_Interest_FOR_A: () = {
                extern crate example_traits;
                impl<T> example_traits::Interest for A<T>
                    where T: example_traits::Interest
                {
                    fn interesting(&self) -> bool {
                        match *self {
                            A::B(ref __binding_0, ref __binding_1,) => {
                                false ||
                                    example_traits::Interest::interesting(__binding_0) ||
                                    example_traits::Interest::interesting(__binding_1)
                            }
                            A::C(ref __binding_0,) => {
                                false ||
                                    example_traits::Interest::interesting(__binding_0)
                            }
                        }
                    }
                }
            };
        }
    }
}

For more example usage, consider investigating the abomonation_derive crate, which makes use of this crate, and is fairly simple.

More Repositories

1

rust-cpp

Embed C++ directly inside your rust code!
Rust
769
star
2

git-revise

A handy tool for doing efficient in-memory commit rebases & fixups
Python
712
star
3

meteor-routecore

Client and server side rendering/routing powered by React
JavaScript
84
star
4

meteor-device-detection

(NO LONGER SUPPORTED) Client-Side Device Type Detection & Template Switching with Optional Meteor-Router Support
JavaScript
69
star
5

micro-coreutils

An implementation of the unix commands yes, cat, and echo in as few bytes of executable as possible
Assembly
57
star
6

gh-release-watch

Watches github repositories for new tags, and lets you know when they are released
JavaScript
44
star
7

meteor-clojurescript

A Clojurescript package for Meteor
JavaScript
32
star
8

cargo-no-std-check

Check that a crate builds without libstd
Rust
22
star
9

phlay

Phlay your commits onto Phabricator
Python
19
star
10

ctrs

watt-based inline procedural macros
Rust
14
star
11

dyno

Rust dynamic objects
Rust
10
star
12

object-provider

Support for requesting objects from other objects dynamically based on type
Rust
10
star
13

refptr

Invasive reference counting in Rust
Rust
10
star
14

simple-lisp-parser-in-c

A simple lisp parser in c, because why not!
C
9
star
15

asm-lang

A simple compiler for a basic language written in x86-64 assembly language
Assembly
8
star
16

mc4d

A visualization of a 4d minecraft-like world
C++
7
star
17

abomonation_derive

A macros 1.1 #[derive(Abomonation)] implementation for the abomonation crate
Rust
6
star
18

literalext

A helper crate for interpreting proc-macro `Literal` values
Rust
5
star
19

atomic_ref

An atomic reference hack for rust
Rust
5
star
20

rust-try-let

A syntax extension for a basic try-let form
Rust
5
star
21

unsauron

Eliminate the eye of sauron
Rust
3
star
22

icecc-osx-moztor

Icecream Configuration for builds in Toronto on Mac OS X
C++
3
star
23

rustlex

A lexer for rust tokens
Rust
3
star
24

ducky

A statically duck-typed language. Very much WIP.
Rust
3
star
25

nolto

Strip -C lto if it is passed to rustc.
Rust
2
star
26

cghelper

Rust
2
star
27

dist-xprs-example

Example generated code for bug 1293362 for obj/dist/xprs
Rust
2
star
28

breaktarget

nonlocal breaks in rust
Rust
2
star
29

data_arena

rust arena allocator for data types
Rust
2
star
30

ptrpack

rust crate to pack a tuple of values into a single integer
Rust
2
star
31

enum_extract

Helper rust macros for extracting single enum variants
Rust
2
star
32

fauxenstream

A fake tokenstream implementation on stable rust
Rust
2
star
33

ejasm

A really simple stack-based VM, inspired by Erik and Jake
C++
2
star
34

tt-match

macro_rules!-style TokenTree matcher for `syn`
Rust
2
star
35

myst

A dynamically typed, functional *script language with trivial JavaScript interop
JavaScript
2
star
36

rusty-llvm

"safe" bindings to LLVM from Rust
Rust
1
star
37

amethyst_516

Rust
1
star
38

pipdl-rs

ipdl parser in rust with no dependencies
Rust
1
star
39

rustc_ice_15042017

Rust
1
star
40

stacker

An implementation of stacker in asm with no libraries
Assembly
1
star
41

synmap

Rust
1
star
42

cderive

[EXPERIMENTAL] custom derives for c
Rust
1
star
43

serde-bser

BSER serde deserializer
Rust
1
star
44

cgc

asd
Rust
1
star
45

parser-comb

A (wildly incomplete and buggy) parser combinator library in rust
Rust
1
star
46

meteor-lazy-packages

lazy packages for meteor
JavaScript
1
star
47

aumc

Compiler for the aum programming language
Rust
1
star
48

cachemap

Insert only arena-like hashmap
Rust
1
star
49

phab-creationMethod-ext

JavaScript
1
star
50

oxy

oxygen
Rust
1
star
51

objc_methname

A crummy crate for using derive() to add objective c method names interned into the right sections.
Rust
1
star
52

vendor_nested_empty_directory_cargo

Rust
1
star
53

yaccia

Yet Another C Compiler In Assembly
Assembly
1
star
54

nowarn

A simple command wrapper which discards stderr on success
Rust
1
star
55

asmc-blog

An exploration of writing a compiler in assembly
Shell
1
star
56

pore

A Pretty Okay Remote Environment
Python
1
star
57

lambda-macro

A lambda! macro for rust
Rust
1
star
58

relex

Interpret rust tokens provided by proc-macro or proc-macro2.
Rust
1
star
59

nsstring

Mirror of mozilla-central/xpcom/rust/nsstring for use in crates outside of mozilla-central (manually updated)
Rust
1
star
60

dpp

Rust
1
star
61

machwrapper

A super simple wrapper around mach (the mozilla build system) which makes my life easier
Shell
1
star
62

meteor-lazy

UNFINISHED - Lazy loading for meteor
JavaScript
1
star
63

llvm_testbed

A simple tool for seeing how to generate llvm IR
Python
1
star
64

meteor-device-detection-example

An example for meteor-device-detection: https://github.com/mystor/meteor-device-detection/
JavaScript
1
star