Skip to content

Commit

Permalink
Update example style to remove #[macro_use]
Browse files Browse the repository at this point in the history
Fixes #211
  • Loading branch information
TedDriggs committed Feb 26, 2024
1 parent 10152f1 commit cb79ad1
Show file tree
Hide file tree
Showing 11 changed files with 57 additions and 90 deletions.
53 changes: 26 additions & 27 deletions derive_builder/README.md
Expand Up @@ -12,8 +12,7 @@
## How it Works

```rust
#[macro_use]
extern crate derive_builder;
use derive_builder::Builder;

#[derive(Default, Builder, Debug)]
#[builder(setter(into))]
Expand Down Expand Up @@ -105,40 +104,40 @@ It's as simple as three steps:
1. Add `derive_builder` to your `Cargo.toml` either manually or
with [cargo-edit](https://github.com/killercup/cargo-edit):

- `cargo add derive_builder`
- `cargo add derive_builder`

2. Add `use derive_builder::Builder;`
3. Annotate your struct with `#[derive(Builder)]`

## Usage and Features

- **Chaining**: The setter calls can be chained, because they consume and return `&mut self` by default.
- **Builder patterns**: You can opt into other builder patterns by preceding your struct (or field) with `#[builder(pattern = "owned")]` or `#[builder(pattern = "immutable")]`.
- **Extensible**: You can still define your own implementations for the builder struct and define additional methods. Just make sure to name them differently than the setter and build methods.
- **Documentation and attributes**: Setter methods can be documented by simply documenting the corresponding field. Similarly `#[cfg(...)]` and `#[allow(...)]` attributes are also applied to the setter methods.
- **Hidden fields**: You can skip setters via `#[builder(setter(skip))]` on each field individually.
- **Setter visibility**: You can opt into private setter by preceding your struct with `#[builder(private)]`.
- **Setter type conversions**: With `#[builder(setter(into))]`, setter methods will be generic over the input types – you can then supply every argument that implements the [`Into`][into] trait for the field type.
- **Setter strip option**: With `#[builder(setter(strip_option))]`, setter methods will take `T` as parameter'type for field of type `Option<T>`.
- **Collection setters**: Adding `#[builder(setter(each(name = "method_name")))]` to fields whose types implement `Default` and `Extend` will generate a setter which adds items to the builder collection for that field. It's possible for these setters to be generic over the `Into<T>` trait too, like so: `#[builder(setter(each(name = "foo", into)))]`.
- **Builder field visibility**: You can use `#[builder(field(private))]` or `..(public)`, to set field visibility of your builder.
- **Generic structs**: Are also supported, but you **must not** use a type parameter named `VALUE`, if you also activate setter type conversions.
- **Default values**: You can use `#[builder(default)]` to delegate to the `Default` implementation or any explicit value via ` = ".."`. This works both on the struct and field level.
- **Pre-build validation**: You can use `#[builder(build_fn(validate = "path::to::fn"))]` to add your own validation before the target struct is generated.
- **Build method suppression**: You can use `#[builder(build_fn(skip))]` to disable auto-implementation of the build method and provide your own.
- **Custom build method error types**: You can use `#[builder(build_fn(error = "path::to::Error"))]` to have your builder return an error type of your choosing. By default, the macro will emit an error type alongside the builder.
- **Builder derivations**: You can use `#[builder(derive(Trait1, Trait2, ...))]` to have the builder derive additonal traits. All builders derive `Default` and `Clone`, so you should not declare those in this attribute.
- **Pass-through attributes**: Use `#[builder_struct_attr(...)]`, `#[builder_impl_attr(...)]`, `#[builder_field_attr(...)]`, and `#[builder_setter_attr(...)]` to declare attributes that will be added to the relevant part of the generated builder.
- **no_std support**: Just add `#[builder(no_std)]` to your struct, use feature `alloc`, and add `extern crate alloc` to your crate.
- **No alloc no_std support**: Do not use `alloc` feature and then either add `#[builder(no_std, build_fn(error(validation_error = false)))]` or `#[builder(no_std, build_fn(error = "path::to::Error"))]` to your struct.
- **Renaming and re-export support**: Use `#[builder(crate = "...")]` to set the root for `derive_builder`. This is useful if you want to rename `derive_builder` in `Cargo.toml` or if your crate is re-exporting `derive_builder::Builder` and needs the generated code to not directly reference the `derive_builder` crate.
- **Chaining**: The setter calls can be chained, because they consume and return `&mut self` by default.
- **Builder patterns**: You can opt into other builder patterns by preceding your struct (or field) with `#[builder(pattern = "owned")]` or `#[builder(pattern = "immutable")]`.
- **Extensible**: You can still define your own implementations for the builder struct and define additional methods. Just make sure to name them differently than the setter and build methods.
- **Documentation and attributes**: Setter methods can be documented by simply documenting the corresponding field. Similarly `#[cfg(...)]` and `#[allow(...)]` attributes are also applied to the setter methods.
- **Hidden fields**: You can skip setters via `#[builder(setter(skip))]` on each field individually.
- **Setter visibility**: You can opt into private setter by preceding your struct with `#[builder(private)]`.
- **Setter type conversions**: With `#[builder(setter(into))]`, setter methods will be generic over the input types – you can then supply every argument that implements the [`Into`][into] trait for the field type.
- **Setter strip option**: With `#[builder(setter(strip_option))]`, setter methods will take `T` as parameter'type for field of type `Option<T>`.
- **Collection setters**: Adding `#[builder(setter(each(name = "method_name")))]` to fields whose types implement `Default` and `Extend` will generate a setter which adds items to the builder collection for that field. It's possible for these setters to be generic over the `Into<T>` trait too, like so: `#[builder(setter(each(name = "foo", into)))]`.
- **Builder field visibility**: You can use `#[builder(field(private))]` or `..(public)`, to set field visibility of your builder.
- **Generic structs**: Are also supported, but you **must not** use a type parameter named `VALUE`, if you also activate setter type conversions.
- **Default values**: You can use `#[builder(default)]` to delegate to the `Default` implementation or any explicit value via ` = ".."`. This works both on the struct and field level.
- **Pre-build validation**: You can use `#[builder(build_fn(validate = "path::to::fn"))]` to add your own validation before the target struct is generated.
- **Build method suppression**: You can use `#[builder(build_fn(skip))]` to disable auto-implementation of the build method and provide your own.
- **Custom build method error types**: You can use `#[builder(build_fn(error = "path::to::Error"))]` to have your builder return an error type of your choosing. By default, the macro will emit an error type alongside the builder.
- **Builder derivations**: You can use `#[builder(derive(Trait1, Trait2, ...))]` to have the builder derive additonal traits. All builders derive `Default` and `Clone`, so you should not declare those in this attribute.
- **Pass-through attributes**: Use `#[builder_struct_attr(...)]`, `#[builder_impl_attr(...)]`, `#[builder_field_attr(...)]`, and `#[builder_setter_attr(...)]` to declare attributes that will be added to the relevant part of the generated builder.
- **no_std support**: Just add `#[builder(no_std)]` to your struct, use feature `alloc`, and add `extern crate alloc` to your crate.
- **No alloc no_std support**: Do not use `alloc` feature and then either add `#[builder(no_std, build_fn(error(validation_error = false)))]` or `#[builder(no_std, build_fn(error = "path::to::Error"))]` to your struct.
- **Renaming and re-export support**: Use `#[builder(crate = "...")]` to set the root for `derive_builder`. This is useful if you want to rename `derive_builder` in `Cargo.toml` or if your crate is re-exporting `derive_builder::Builder` and needs the generated code to not directly reference the `derive_builder` crate.

For more information and examples please take a look at our [documentation][doc].

## Gotchas

- Tuple structs and unit structs are not supported as they have no field names. We do not intend to support them.
- When defining a generic struct, you cannot use `VALUE` as a generic parameter as this is what all setters are using.
- Tuple structs and unit structs are not supported as they have no field names. We do not intend to support them.
- When defining a generic struct, you cannot use `VALUE` as a generic parameter as this is what all setters are using.

## [Documentation][doc]

Expand All @@ -157,8 +156,8 @@ Yes, we keep a changelog.

Licensed under either of

- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)

at your option.

Expand Down
5 changes: 2 additions & 3 deletions derive_builder/examples/channel.rs
@@ -1,10 +1,9 @@
#![allow(dead_code)]

#[macro_use]
extern crate derive_builder;

use std::convert::From;

use derive_builder::Builder;

#[derive(PartialEq, Default, Debug, Clone)]
struct Uuid(i32);
#[derive(PartialEq, Default, Debug, Clone)]
Expand Down
3 changes: 1 addition & 2 deletions derive_builder/examples/custom_constructor.rs
@@ -1,7 +1,6 @@
#![allow(dead_code)]

#[macro_use]
extern crate derive_builder;
use derive_builder::Builder;

#[derive(Debug, Clone)]
pub enum ContentType {
Expand Down
3 changes: 1 addition & 2 deletions derive_builder/examples/custom_defaults.rs
@@ -1,5 +1,4 @@
#[macro_use]
extern crate derive_builder;
use derive_builder::Builder;

#[derive(Builder, PartialEq, Debug)]
struct Lorem {
Expand Down
6 changes: 2 additions & 4 deletions derive_builder/examples/custom_error.rs
Expand Up @@ -5,12 +5,10 @@
//! the generated `FooBuilderError` type is valid.
#![allow(dead_code)]

#[macro_use]
extern crate derive_builder;

use derive_builder::UninitializedFieldError;
use std::fmt;

use derive_builder::{Builder, UninitializedFieldError};

fn validate_age(builder: &ExampleBuilder) -> Result<(), Error> {
match builder.age {
Some(age) if age > 150 => Err(Error::UnrealisticAge(age)),
Expand Down
5 changes: 1 addition & 4 deletions derive_builder/examples/custom_error_generic.rs
Expand Up @@ -3,10 +3,7 @@
//! Note the use of the type parameter in the `#[builder(...)]` attribute.
#![allow(dead_code)]

#[macro_use]
extern crate derive_builder;

use derive_builder::UninitializedFieldError;
use derive_builder::{Builder, UninitializedFieldError};

trait Popular {
fn is_popular(&self) -> bool;
Expand Down
3 changes: 1 addition & 2 deletions derive_builder/examples/deny_missing_docs.rs
Expand Up @@ -3,8 +3,7 @@
//! NOTE: This can only be tested in examples, but not integration tests.
#![deny(missing_docs)]

#[macro_use]
extern crate derive_builder;
use derive_builder::Builder;

/// Traditional form of communication.
#[derive(Debug, Builder)]
Expand Down
3 changes: 1 addition & 2 deletions derive_builder/examples/doc_example.rs
Expand Up @@ -2,8 +2,7 @@
//
// cargo expand --example doc_example

#[macro_use]
extern crate derive_builder;
use derive_builder::Builder;

#[allow(dead_code)]
#[derive(Builder)]
Expand Down
3 changes: 1 addition & 2 deletions derive_builder/examples/readme_example.rs
Expand Up @@ -3,8 +3,7 @@
// cargo expand --example readme_example
#![allow(dead_code)]

#[macro_use]
extern crate derive_builder;
use derive_builder::Builder;

#[derive(Default, Builder, Debug)]
#[builder(setter(into))]
Expand Down
5 changes: 2 additions & 3 deletions derive_builder/examples/validation.rs
@@ -1,11 +1,10 @@
//! This example illustrates the use of `validate` to add a pre-build validation
//! step.

#[macro_use]
extern crate derive_builder;
use derive_builder::Builder;

#[derive(Builder, Debug, PartialEq)]
#[builder(build_fn(validate = "Self::validate"))]
#[builder(build_fn(validate = Self::validate))]
struct Lorem {
pub ipsum: u8,
}
Expand Down
58 changes: 19 additions & 39 deletions derive_builder/src/lib.rs
Expand Up @@ -12,8 +12,7 @@
//! ## What you write
//!
//! ```rust
//! #[macro_use]
//! extern crate derive_builder;
//! use derive_builder::Builder;
//!
//! #[derive(Builder)]
//! struct Lorem {
Expand All @@ -26,9 +25,7 @@
//! ## What you get
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::UninitializedFieldError;
//! # use derive_builder::{Builder, UninitializedFieldError};
//! #
//! # struct Lorem {
//! # ipsum: u32,
Expand Down Expand Up @@ -76,7 +73,7 @@
//! Let's look again at the example above. You can now build structs like this:
//!
//! ```rust
//! # #[macro_use] extern crate derive_builder;
//! # use derive_builder::Builder;
//! # #[derive(Builder)] struct Lorem { ipsum: u32 }
//! # fn try_main() -> Result<(), Box<dyn std::error::Error>> {
//! let x: Lorem = LoremBuilder::default().ipsum(42).build()?;
Expand All @@ -89,7 +86,7 @@
//! So let's make this call conditional
//!
//! ```rust
//! # #[macro_use] extern crate derive_builder;
//! # use derive_builder::Builder;
//! # #[derive(Builder)] struct Lorem { ipsum: u32 }
//! # fn try_main() -> Result<(), Box<dyn std::error::Error>> {
//! # let geek = true;
Expand Down Expand Up @@ -164,8 +161,7 @@
//! The types of skipped fields must implement `Default`.
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::Builder;
//! #
//! #[derive(Builder)]
//! struct HiddenField {
Expand All @@ -188,8 +184,7 @@
//! as `Option<T>`.
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::Builder;
//! #
//! #[derive(Builder)]
//! struct SetterOptOut {
Expand Down Expand Up @@ -223,8 +218,7 @@
//! You can override this:
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::Builder;
//! #
//! #[derive(Builder)]
//! #[builder(name = "FooConstructor")]
Expand Down Expand Up @@ -254,8 +248,7 @@
//! `#[builder(setter(into))]` to either a field or the whole struct.
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::Builder;
//! #
//! #[derive(Builder, Debug, PartialEq)]
//! struct Lorem {
Expand All @@ -279,8 +272,7 @@
//! `#[builder(setter(strip_option))]` to either a single field or the whole struct.
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::Builder;
//! #
//! #[derive(Builder, Debug, PartialEq)]
//! struct Lorem {
Expand Down Expand Up @@ -316,8 +308,7 @@
//! to add `#![feature(try_from)]` to your crate to use it.
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::Builder;
//! #[derive(Builder, Debug, PartialEq)]
//! #[builder(try_setter, setter(into))]
//! struct Lorem {
Expand Down Expand Up @@ -356,8 +347,7 @@
//! The expression will be evaluated with each call to `build`.
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::Builder;
//! #
//! #[derive(Builder, Debug, PartialEq)]
//! struct Lorem {
Expand Down Expand Up @@ -390,8 +380,7 @@
//! [`Default`]: https://doc.rust-lang.org/std/default/trait.Default.html
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::Builder;
//! #
//! # #[derive(Builder, PartialEq, Debug)]
//! struct Lorem {
Expand Down Expand Up @@ -431,8 +420,7 @@
//! ## Generic Structs
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::Builder;
//! #
//! #[derive(Builder, Debug, PartialEq, Default, Clone)]
//! struct GenLorem<T: Clone> {
Expand Down Expand Up @@ -464,8 +452,7 @@
//! the `Ok` variant is not used by the `build` method.
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::Builder;
//! #
//! #[derive(Builder, Debug, PartialEq)]
//! #[builder(build_fn(validate = "Self::validate"))]
Expand Down Expand Up @@ -505,8 +492,7 @@
//! You can derive additional traits on the builder, including traits defined by other crates:
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::Builder;
//! #
//! #[derive(Builder, Clone)]
//! #[builder(derive(Debug, PartialEq, Eq))]
Expand Down Expand Up @@ -536,8 +522,7 @@
//! those used by Serde, Diesel, or others.
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::Builder;
//! #
//! #[derive(Builder)]
//! struct Lorem {
Expand All @@ -564,8 +549,7 @@
//! - `builder_setter_attr` adds attributes to the setter in the `impl` block.
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::Builder;
//! #
//! #[derive(Builder)]
//! #[builder(derive(serde::Serialize))]
Expand All @@ -587,7 +571,6 @@
//! By default, `build` returns an autogenerated error type:
//!
//! ```rust
//! # extern crate derive_builder;
//! # use derive_builder::UninitializedFieldError;
//! # use std::fmt::{self, Display};
//! #
Expand All @@ -613,9 +596,7 @@
//!
//! Alternatively, you can specify your own error type:
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::UninitializedFieldError;
//! # use derive_builder::{Builder, UninitializedFieldError};
//! #
//! #[derive(Builder, Debug, PartialEq)]
//! #[builder(build_fn(error = "OurLoremError"))]
Expand All @@ -640,8 +621,7 @@
//! Instead of having an `Option`, you can have whatever type you like:
//!
//! ```rust
//! # #[macro_use]
//! # extern crate derive_builder;
//! # use derive_builder::Builder;
//! #[derive(Debug, PartialEq, Default, Builder, Clone)]
//! #[builder(derive(Debug, PartialEq))]
//! struct Lorem {
Expand Down

0 comments on commit cb79ad1

Please sign in to comment.