all_tuples_with_size!() { /* proc-macro */ }
Expand description
Helper macro to generate tuple pyramids with their length. Useful to generate scaffolding to
work around Rust lacking variadics. Invoking all_tuples_with_size!(impl_foo, start, end, P, Q, ..)
invokes impl_foo
providing ident tuples through arity start..=end
preceded by their length.
If you don’t require the length of the tuple, see all_tuples!
.
§Examples
§Single parameter
struct Foo<T> {
// ..
}
trait WrappedInFoo {
type Tup;
const LENGTH: usize;
}
macro_rules! impl_wrapped_in_foo {
($N:expr, $($T:ident),*) => {
impl<$($T),*> WrappedInFoo for ($($T,)*) {
type Tup = ($(Foo<$T>,)*);
const LENGTH: usize = $N;
}
};
}
all_tuples_with_size!(impl_wrapped_in_foo, 0, 15, T);
// impl_wrapped_in_foo!(0);
// impl_wrapped_in_foo!(1, T0);
// impl_wrapped_in_foo!(2, T0, T1);
// ..
// impl_wrapped_in_foo!(15, T0 .. T14);
§Multiple parameters
trait Append {
type Out<Item>;
fn append<Item>(tup: Self, item: Item) -> Self::Out<Item>;
}
impl Append for () {
type Out<Item> = (Item,);
fn append<Item>(_: Self, item: Item) -> Self::Out<Item> {
(item,)
}
}
macro_rules! impl_append {
($N:expr, $(($P:ident, $p:ident)),*) => {
impl<$($P),*> Append for ($($P,)*) {
type Out<Item> = ($($P),*, Item);
fn append<Item>(($($p,)*): Self, item: Item) -> Self::Out<Item> {
($($p),*, item)
}
}
}
}
all_tuples_with_size!(impl_append, 1, 15, P, p);
// impl_append!(1, (P0, p0));
// impl_append!(2, (P0, p0), (P1, p1));
// impl_append!(3, (P0, p0), (P1, p1), (P2, p2));
// ..
// impl_append!(15, (P0, p0) .. (P14, p14));
#[doc(fake_variadic)]
To improve the readability of your docs when implementing a trait for
tuples or fn pointers of varying length you can use the rustdoc-internal fake_variadic
marker.
All your impls are collapsed and shown as a single impl Trait for (F₁, F₂, …, Fₙ)
.
The all_tuples!
macro does most of the work for you, the only change to your implementation macro
is that you have to accept attributes using $(#[$meta:meta])*
.
Since this feature requires a nightly compiler, it’s only enabled on docs.rs by default. Add the following to your lib.rs if not already present:
// `rustdoc_internals` is needed for `#[doc(fake_variadics)]`
#![allow(internal_features)]
#![cfg_attr(any(docsrs, docsrs_dep), feature(rustdoc_internals))]
trait Variadic {}
impl Variadic for () {}
macro_rules! impl_variadic {
($N:expr, $(#[$meta:meta])* $(($P:ident, $p:ident)),*) => {
$(#[$meta])*
impl<$($P),*> Variadic for ($($P,)*) {}
}
}
all_tuples_with_size!(#[doc(fake_variadic)] impl_variadic, 1, 15, P, p);