#macro-derive #derive #macro #custom

no-std custom_derive

(Note: superseded by macro-attr) This crate provides a macro that enables the use of custom derive attributes

6 releases

Uses old Rust 2015

0.1.7 Nov 21, 2016
0.1.5 Mar 30, 2016
0.1.4 Jan 18, 2016
0.1.2 Sep 16, 2015
0.1.1 Aug 16, 2015

#547 in Rust patterns

Download history 31544/week @ 2024-06-16 26533/week @ 2024-06-23 22315/week @ 2024-06-30 47204/week @ 2024-07-07 54739/week @ 2024-07-14 56586/week @ 2024-07-21 59737/week @ 2024-07-28 48659/week @ 2024-08-04 72228/week @ 2024-08-11 65852/week @ 2024-08-18 36132/week @ 2024-08-25 42475/week @ 2024-09-01 42973/week @ 2024-09-08 49358/week @ 2024-09-15 47866/week @ 2024-09-22 48134/week @ 2024-09-29

191,653 downloads per month
Used in 502 crates (35 directly)

MIT/Apache

15KB
270 lines

custom_derive!

Note: This crate has been superseded by macro-attr.

This crate provides a macro that enables the use of custom derive attributes.

Links

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.


lib.rs:

Note: This crate has been superseded by macro-attr.

This crate provides a macro that enables the use of custom derive attributes.

To use it, make sure you link to the crate like so:

#[macro_use] extern crate custom_derive;

Note: the custom_derive! macro itself is not documented, as the automatic documentation for it would be uselessly huge and incomprehensible.

<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>

Usage

The macro should be used to wrap an entire single enum or struct declaration, including its attributes (both derive and others). All derivation attributes which the macro does not recognise will be assumed to be custom, and treated accordingly.

custom_derive! assumes that custom derivations are implemented as macros (of the same name). For example, here is a simple derivation macro:

#[macro_use] extern crate custom_derive;

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

trait ReprType {
type Repr;
}

macro_rules! TypeName {
(() $(pub)* enum $name:ident $($tail:tt)*) => { TypeName! { @impl $name } };
(() $(pub)* struct $name:ident $($tail:tt)*) => { TypeName! { @impl $name } };

(@impl $name:ident) => {
impl TypeName for $name {
fn type_name() -> &'static str { stringify!($name) }
}
};
}

macro_rules! TryFrom {
(($repr:ty) $(pub)* enum $name:ident $($tail:tt)*) => {
impl ReprType for $name {
type Repr = $repr;
}
};
}

custom_derive! {
#[allow(dead_code)]
#[repr(u8)]
#[derive(Clone, Copy, Debug, TryFrom(u8), TypeName)]
enum Foo { A, B }
}

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

First, note that custom_derive! passes any arguments on the derivation attribute to the macro. In the case of attributes without any arguments, () is passed instead.

Secondly, the macro is passed the entire item, sans attributes. It is the derivation macro's job to parse the item correctly.

Third, each derivation macro is expected to result in zero or more items, not including the item itself. As a result, it is not possible to mutate the item in any way, or attach additional attributes to it.

Finally, @impl is merely a trick to pack multiple, different functions into a single macro. The sequence has no special meaning; it is simply distinct from the usual invocation syntax.

No runtime deps