Crate derive_utils
source · [−]Expand description
A procedural macro helper for easily writing derives macros for enums.
Examples
quick_derive!
macro make easy to write proc_macro_derive
like deriving trait to enum so long as all variants are implemented that trait.
use derive_utils::quick_derive;
use proc_macro::TokenStream;
#[proc_macro_derive(Iterator)]
pub fn derive_iterator(input: TokenStream) -> TokenStream {
quick_derive! {
input,
// trait path
std::iter::Iterator,
// trait definition
trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
fn size_hint(&self) -> (usize, Option<usize>);
}
}
}
#[proc_macro_derive(ExactSizeIterator)]
pub fn derive_exact_size_iterator(input: TokenStream) -> TokenStream {
quick_derive! {
input,
// trait path
std::iter::ExactSizeIterator,
// super trait's associated types
<Item>,
// trait definition
trait ExactSizeIterator: Iterator {
fn len(&self) -> usize;
}
}
}
#[proc_macro_derive(Future)]
pub fn derive_future(input: TokenStream) -> TokenStream {
quick_derive! {
input,
// trait path
std::future::Future,
// trait definition
trait Future {
type Output;
fn poll(
self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Self::Output>;
}
}
}
Generated code
When deriving for enum like the following:
#[derive(Iterator, ExactSizeIterator, Future)]
enum Enum<A, B> {
A(A),
B(B),
}
Code like this will be generated:
enum Enum<A, B> {
A(A),
B(B),
}
impl<A, B> std::iter::Iterator for Enum<A, B>
where
A: std::iter::Iterator,
B: std::iter::Iterator<Item = <A as std::iter::Iterator>::Item>,
{
type Item = <A as std::iter::Iterator>::Item;
fn next(&mut self) -> Option<Self::Item> {
match self {
Enum::A(x) => x.next(),
Enum::B(x) => x.next(),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
match self {
Enum::A(x) => x.size_hint(),
Enum::B(x) => x.size_hint(),
}
}
}
impl<A, B> std::iter::ExactSizeIterator for Enum<A, B>
where
A: std::iter::ExactSizeIterator,
B: std::iter::ExactSizeIterator<Item = <A as Iterator>::Item>,
{
fn len(&self) -> usize {
match self {
Enum::A(x) => x.len(),
Enum::B(x) => x.len(),
}
}
}
impl<A, B> std::future::Future for Enum<A, B>
where
A: std::future::Future,
B: std::future::Future<Output = <A as std::future::Future>::Output>,
{
type Output = <A as std::future::Future>::Output;
fn poll(
self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Self::Output> {
unsafe {
match self.get_unchecked_mut() {
Enum::A(x) => std::pin::Pin::new_unchecked(x).poll(cx),
Enum::B(x) => std::pin::Pin::new_unchecked(x).poll(cx),
}
}
}
}
Macros
A macro for making easy to write proc_macro_derive
like deriving trait to
enum so long as all variants are implemented that trait.
Structs
A structure to make trait implementation to enums more efficient.
A builder for implementing a trait for enums.
Functions
A function for creating proc_macro_derive
like deriving trait to enum so
long as all variants are implemented that trait.