Skip to content
Custom derivation macro for Rust
Rust
Branch: master
Clone or download

Latest commit

Latest commit 1252f25 Nov 21, 2016

Files

Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.cargo
enum_derive
newtype_derive Bump to v0.2.1. Nov 21, 2016
scripts @ f96ff34 Replace scripts dir with toolbox submodule. Nov 14, 2016
src Doc pass before publish. Nov 21, 2016
tests Bump to v0.2.1. Nov 21, 2016
.gitignore Added .local to .gitignore. Dec 1, 2015
.gitmodules Replace scripts dir with toolbox submodule. Nov 14, 2016
.travis.yml Add support for hybrid derives. Nov 10, 2016
Cargo.toml Bump to v0.2.1. Nov 21, 2016
LICENSE Doc pass before publish. Nov 21, 2016
README.md Doc pass before publish. Nov 21, 2016

README.md

macro-attr

This crate provides the macro_attr! macro that enables the use of custom, macro-based attributes and derivations. Supercedes the custom_derive crate.

Links

Compatibility

macro-attr is compatible with Rust 1.2 and higher.

Example

#[macro_use] extern crate macro_attr;

// Define some traits to be derived.

trait TypeName {
    fn type_name() -> &'static str;
}

trait ReprType {
    type Repr;
}

// Define macros which derive implementations of these macros.

macro_rules! TypeName {
    // We can support any kind of item we want.
    (() $(pub)* enum $name:ident $($tail:tt)*) => { TypeName! { @impl $name } };
    (() $(pub)* struct $name:ident $($tail:tt)*) => { TypeName! { @impl $name } };

    // Inner rule to cut down on repetition.
    (@impl $name:ident) => {
        impl TypeName for $name {
            fn type_name() -> &'static str { stringify!($name) }
        }
    };
}

macro_rules! ReprType {
    // Note that we use a "derivation argument" here for the `$repr` type.
    (($repr:ty) $(pub)* enum $name:ident $($tail:tt)*) => {
        impl ReprType for $name {
            type Repr = $repr;
        }
    };
}

// Here is a macro that *modifies* the item.

macro_rules! rename_to {
    (
        ($new_name:ident),
        then $cb:tt,
        $(#[$($attrs:tt)*])*
        enum $_old_name:ident $($tail:tt)*
    ) => {
        macro_attr_callback! {
            $cb,
            $(#[$($attrs)*])*
            enum $new_name $($tail)*
        }
    };
}

macro_attr! {
    #[allow(dead_code)]
    #[derive(Clone, Copy, Debug, ReprType!(u8), TypeName!)]
    #[rename_to!(Bar)]
    #[repr(u8)]
    enum Foo { A, B }
}

fn main() {
    let bar = Bar::B;
    let v = bar as <Bar as ReprType>::Repr;
    let msg = format!("{}: {:?} ({:?})", Bar::type_name(), bar, v);
    assert_eq!(msg, "Bar: B (1)");
}

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions.

You can’t perform that action at this time.