withers_derive

Crates.iowithers_derive
lib.rswithers_derive
version0.2.0
sourcesrc
created_at2018-04-02 11:02:52.494501
updated_at2018-04-02 15:32:55.217195
descriptionA macro to implement wither methods for properties of a struct.
homepage
repositoryhttps://github.com/Rowmance/withers-derive
max_upload_size
id58601
size7,211
Roman (Rowmance)

documentation

README

Withers Derive

Latest Version

A macro to implement wither methods for properties of a struct.

The Wither Pattern

The wither pattern consists of using methods to mutate an instance of a struct, generally beginning with with_.

#[derive(Withers, Default)]
struct Foo {
    bar: u32,
    baz: Option<bool>
}

fn main() {
    let instance = foo::default()
        .with_bar(32)
        .with_baz(Some(false));
}

This implementation generates consuming methods, so the instance is mutated and consumed, and can no longer be used in its previous state.

Wither vs Builder

The wither pattern bares strong resemblance to the builder pattern, though:

  • The wither pattern does not require a separate struct.
  • The wither pattern allows easy mutation of existing instances (this is useful in conjunction with clone and/or copy).
  • The wither pattern will not lead to runtime errors due to uninitialised properties.

However:

  • The wither pattern requires a struct to be able to be initialised with default and sensible values. Otherwise an error which could be caught on initialisation could cause unexpected behaviour down the line.
  • A builder can usually be stored and used to generate several instances of structs, whereas withers operate on instances directly.

If these feel like they may be issues for you, the derive_builder crate may suit your needs better.

What it does

The following code

#[macro_use]
extern crate withers_derive;

#[derive(Withers)]
struct Foo {
   bar: u32,
   baz: Option<bool>
}

Will generate code akin to

struct Foo {
    bar: u32,
    baz: Option<bool>
}

#[allow(dead_code)]
impl Foo {
    fn with_bar(mut self, value: u32) -> Self {
        self.bar = value;
        self
    }

    fn with_baz(mut self, value: Option<bool>) -> Self {
        self.baz = value;
        self
    }
}

Quick Start

  • Add the wither_derive dependency to your Cargo.toml file.
  • Import the crate and macro with
#[macro_use]
extern crate withers_derive;
  • Annotate structs with #[derive(Withers)].

License

MIT License

Contributing

Please fork the repository and raise pull requests into master. Larger code changes should be tracked with GitHub issues.

Commit count: 12

cargo fmt