builder_macro 0.1.0

A macro to generate structs and a corresponding builder
Documentation
# Builder Macro


This crate contains a `builder!` macro to declare a struct and a corresponding builder.

The macro is inspired from [jadpole/builder-macro][1], and is designed to
remove duplication of field declaration, as well as generating appropriate setter methods.

Include the macro inside your crate's `lib.rs` or `main.rs`.

```rust
#[macro_use]

extern crate builder_macro;
```

## Examples


### Non-consuming Builder


The simplest usage of the builder macro to generate a [non-consuming builder][2] is:

```rust,ignore
builder!(BuilderName -> StructName {
    fieldname: Type = Some(default_value), // or None if there is no sensible default
});
```

The above will generate a module private struct and a non-consuming builder with a single private field.

For example, given the following declaration:

```rust
builder!(BuilderName -> StructName {
    value: i32 = Some(1),
});
```

The generated builder and struct will be:

```rust
struct StructName {
    value: i32,
}

#[doc = "Generated struct builder"]

struct BuilderName {
    value: Option<i32>,
}

impl BuilderName {
    /// Construct the builder
    pub fn new() -> BuilderName { BuilderName { value: Some(1), } }

    /// Build the struct
    pub fn build(&self) -> StructName {
        let value = self.value.clone().unwrap();
        StructName{value: value,}
    }

    #[allow(dead_code)]
    /// Specify a value for the $F_NAME field
    pub fn value(&mut self, value: i32) -> &mut Self {
        self.value = Some(value);
        self
    }
}
```

The full macro usage format is:

```rust
// We declare the builder insider a module simply to demonstrate scope
mod inner {
    builder! {
        /// StructName is an example struct.
        /// These docs are copied over to the generated struct.
        pub BuilderName -> StructName {
            /// a_field is an i32 which must be between 0 and 100 inclusive
            // the trailing comma is mandatory due to how the macro is parsed
            pub a_field: i32 = Some(50),

            // None means no default value, a value must be specified when building
            // meta attributes are copied over to the struct's fields
            #[allow(dead_code)]
            a_private_field: &'static str = None,
        }, assertions: {
            assert!(a_field >= 0);
            assert!(a_field <= 100);
            // Yes you can assert on private fields
            assert!(!a_private_field.is_empty());
        }
    }
}

let my_struct = inner::BuilderName::new()
                    .a_private_field("I must set this to a non-empty string")
                    .build();
assert_eq!(50, my_struct.a_field);
```

### Consuming Builder


To generate a [consuming builder][3], instead of using `->`, use `=>` between the builder name and the target struct
name.

```rust
trait Magic {
    fn abracadabra(&mut self) -> i32;
}
struct Dust {
    value: i32,
};
impl Magic for Dust {
    fn abracadabra(&mut self) -> i32 {
        self.value
    }
}

// Note: we use => instead of -> for the consuming variant of the builder
builder!(MyStructBuilder => MyStruct {
    field_trait: Box<Magic> = Some(Box::new(Dust { value: 1 })),
    field_vec: Vec<Box<Magic>> = Some(vec![Box::new(Dust { value: 2 })]),
});

let mut my_struct = MyStructBuilder::new().build();

assert_eq!(my_struct.field_trait.abracadabra(), 1);
assert_eq!(my_struct.field_vec[0].abracadabra(), 2);
```

### Visibility


Generate a builder and struct with module private visibility:

```rust
builder!(MyStructBuilder -> MyStruct {
    field_i32: i32 = Some(123),
    field_str: &'static str = Some("abc"),
});

let my_struct = MyStructBuilder::new()
    .field_i32(456)
    .build();
assert_eq!(my_struct.field_i32, 456);
assert_eq!(my_struct.field_str, "abc"); // uses default
```

Generate a builder and struct with public visibility:

```rust
mod inner {
    builder!(pub MyStructBuilder -> MyStruct {
        pub field_i32: i32 = Some(123),
        field_str: &'static str = Some("abc"),
    });
}

let my_struct = inner::MyStructBuilder::new()
    .field_i32(456)
    .build();
assert_eq!(my_struct.field_i32, 456);

// The next line will fail compilation if uncommented as field_str is private
// assert_eq!(my_struct.field_str, "abc");
```

# License


The MIT License

[1]: http://jadpole.github.io/rust/builder-macro
[2]: https://doc.rust-lang.org/style/ownership/builders.html#non-consuming-builders-preferred
[3]: https://doc.rust-lang.org/style/ownership/builders.html#consuming-builders