Portrait v0.3.0 introduces the derive_delegate
derive filler, which derives trait implementations by delegating trait calls to all fields of a struct/enum. Unlike manually written derive macros that only support one specific trait , derive_delegate
works for any trait with a #[portrait::make]
attribute.
The behavior of derive_delegate
is similar to many macros from the standard library. Here is an all-in-one example that compiles:
#[portrait::make]
trait Foo {
fn new(arg1: i32, arg2: &str, arg3: &mut i64) -> Self;
fn print(&self);
fn clone(&self) -> Self;
#[portrait(derive_delegate(reduce = |a, b| a && b))]
fn eq(&self, other: &Self) -> bool;
}
impl Foo for i32 {
// omitted
}
impl Foo for String {
// omitted
}
#[portrait::derive(Foo with portrait::derive_delegate)]
struct Fields {
a: i32,
b: String,
}
Here is the extra code expanded from #[portrait::derive]
:
Expanded code
const _: () = {
use foo_portrait::imports::*;
impl Foo for Fields
where
i32: Foo,
String: Foo,
{
fn new(arg1: i32, arg2: &str, arg3: &mut i64) -> Self {
Self {
a: Foo::new(arg1, arg2, arg3),
b: Foo::new(arg1, arg2, arg3),
}
}
fn print(&self) {
let Self { a: __portrait_self_0, b: __portrait_self_1 } = self;
Foo::print(__portrait_self_0);
Foo::print(__portrait_self_1);
}
fn clone(&self) -> Self {
let Self { a: __portrait_self_0, b: __portrait_self_1 } = self;
Self {
a: Foo::clone(__portrait_self_0),
b: Foo::clone(__portrait_self_1),
}
}
fn eq(&self, other: &Self) -> bool {
let Self { a: __portrait_self_0, b: __portrait_self_1 } = self;
(|a, b| {
a && b
})(
Foo::eq(
__portrait_self_0,
{
let Self { a: __portrait_other, .. } = self;
__portrait_other
},
),
Foo::eq(
__portrait_self_1,
{
let Self { b: __portrait_other, .. } = self;
__portrait_other
},
),
)
}
}
};
See the documentation on docs.rs for more information.
About portrait
Portrait is a framework for building dynamically-known (at user crate compile time, macro crate runtime) derive/attribute macros by passing both the syn::ItemTrait
and the syn::DeriveInput
/syn::ItemImpl
to the proc macro function. Current macros include log
(log all function calls), default
(always return Default::default()
), delegate
(impl by delegation to a single field) and derive_delegate
(impl by delegation to all fields).