Custom attributes

The Default trait supports the following attributes:

Default enumeration

You can use derivative to derive a default implementation on enumerations! This does not work with rustc's #[derive(Default)]. All you need is to specify what variant is the default value:


#![allow(unused)]
fn main() {
extern crate derivative;
use derivative::Derivative;
#[derive(Debug, Derivative)]
#[derivative(Default)]
enum Enum {
    A,
    #[derivative(Default)]
    B,
}

println!("{:?}", Enum::default()); // B
}

Setting the value of a field

You can use derivative to change the default value of a field in a Default implementation:


#![allow(unused)]
fn main() {
extern crate derivative;
use derivative::Derivative;
#[derive(Debug, Derivative)]
#[derivative(Default)]
struct Foo {
    foo: u8,
    #[derivative(Default(value="42"))]
    bar: u8,
}

println!("{:?}", Foo::default()); // Foo { foo: 0, bar: 42 }
}

new function

You can use derivative to derive a convenience new method for your type that calls Default::default:


#![allow(unused)]
fn main() {
extern crate derivative;
use derivative::Derivative;
#[derive(Debug, Derivative)]
#[derivative(Default(new="true"))]
struct Foo {
    foo: u8,
    bar: u8,
}

println!("{:?}", Foo::new()); // Foo { foo: 0, bar: 0 }
}

Custom bound

The following does not work because derive adds a T: Default bound on the impl Default for Foo<T>:


#![allow(unused)]
fn main() {
extern crate derivative;
use derivative::Derivative;
#[derive(Default)]
struct Foo<T> {
    foo: Option<T>,
}

struct NonDefault;

Foo::<NonDefault>::default(); // gives:
// error: no associated item named `default` found for type `Foo<NonDefault>` in the current scope
//  = note: the method `default` exists but the following trait bounds were not satisfied: `NonDefault : std::default::Default`
}

That bound however is useless as Option<T>: Default for any T. derivative allows you to explicitly specify a bound if the inferred one is not correct:


#![allow(unused)]
fn main() {
extern crate derivative;
use derivative::Derivative;
#[derive(Derivative)]
#[derivative(Default(bound=""))] // don't need any bound
struct Foo<T> {
    foo: Option<T>,
}

struct NonDefault;

Foo::<NonDefault>::default(); // works!
}