                 📖 Guide Book (https://bon-rs.com/guide/overview)
                 Narrative introduction

                 🔍 API Reference (https://bon-rs.com/reference/builder)
                 Attributes API index

# Overview

`bon` is a Rust crate for generating compile-time-checked builders for structs and functions. It also provides idiomatic partial application with optional and named parameters for functions and methods.

If you wonder "Why would I use builders?", see the [motivational blog post](https://bon-rs.com/blog/how-to-do-named-function-arguments-in-rust).

## Function Builder

You can turn a function with positional parameters into a function with named parameters with `#[builder]`.

```rust
use bon::builder;

#[builder]
fn greet(name: &str, level: Option<u32>) -> String {
    let level = level.unwrap_or(0);

    format!("Hello {name}! Your level is {level}")
}

let greeting = greet()
    .name("Bon")
    .level(24) // <- setting `level` is optional, we could omit it
    .call();

assert_eq!(greeting, "Hello Bon! Your level is 24");
```

Any syntax for functions is supported including `async`, fallible, generic functions, `impl Trait`, etc.

Many things are customizable with additional attributes described in the [API reference](https://bon-rs.com/reference/builder), but let's see what else `bon` has to offer.

## Struct Builder

Use `#[derive(Builder)]` to generate a builder for a struct.

```rust
use bon::Builder;

#[derive(Builder)]
struct User {
    name: String,
    is_admin: bool,
    level: Option<u32>,
}

let user = User::builder()
    .name("Bon".to_owned())
    // `level` is optional, we could omit it here
    .level(24)
    // call setters in any order
    .is_admin(true)
    .build();

assert_eq!(user.name, "Bon");
assert_eq!(user.level, Some(24));
assert!(user.is_admin);
```

## Method Builder

Associated methods require `#[bon]` on top of the impl block additionally.

### Method `new`

The method named `new` generates `builder()/build()` methods.

```rust
use bon::bon;

struct User {
    id: u32,
    name: String,
}

#[bon]
impl User {
    #[builder]
    fn new(id: u32, name: String) -> Self {
        Self { id, name }
    }
}

let user = User::builder()
    .id(1)
    .name("Bon".to_owned())
    .build();

assert_eq!(user.id, 1);
assert_eq!(user.name, "Bon");
```

`#[derive(Builder)]` on a struct generates builder API that is fully compatible with placing `#[builder]` on the `new()` method with a signature similar to the struct's fields (more details on the [Compatibility](https://bon-rs.com/guide/basics/compatibility#switching-between-derive-builder-and-builder-on-the-new-method) page).

### Other Methods

All other methods generate `{method_name}()/call()` methods.

```rust
use bon::bon;

struct Greeter {
    name: String,
}

#[bon]
impl Greeter {
    #[builder]
    fn greet(&self, target: &str, prefix: Option<&str>) -> String {
        let prefix = prefix.unwrap_or("INFO");
        let name = &self.name;

        format!("[{prefix}] {name} says hello to {target}")
    }
}

let greeter = Greeter { name: "Bon".to_owned() };

let greeting = greeter
    .greet()
    .target("the world")
    // `prefix` is optional, omitting it is fine
    .call();

assert_eq!(greeting, "[INFO] Bon says hello to the world");
```

Methods with or without `self` are both supported.

## No Panics Possible

Builders generated by `bon`'s macros use the typestate pattern to ensure all required parameters are filled, and the same setters aren't called repeatedly to prevent unintentional overwrites. If something is wrong, a compile error will be created.

| ⭐ Don't forget to give our repo a [star on Github ⭐](https://github.com/elastio/bon)! |
| --------------------------------------------------------------------------------------- |

## What's Next?

What you've seen above is the first page of the 📖 Guide Book. If you want to learn more, jump to the [Basics](https://bon-rs.com/guide/basics) section. And remember: knowledge is power 🐱!

Feel free to jump to code and use the `#[builder]` and `#[derive(Builder)]` once you've seen enough docs to get started.

The [🔍 API Reference](https://bon-rs.com/reference/builder) will help you navigate the attributes once you feel comfortable with the basics of `bon`. Both `#[derive(Builder)]` on structs and `#[builder]` on functions/methods have almost identical attributes API, so the documentation for them is common.

## Installation

Add `bon` to your `Cargo.toml`.



```toml
[dependencies]
bon = "3.7"
```

You can opt out of `std` and `alloc` cargo features with `default-features = false` for `no_std` environments.

## Acknowledgments

This project was heavily inspired by such awesome crates as [`buildstructor`](https://docs.rs/buildstructor), [`typed-builder`](https://docs.rs/typed-builder) and [`derive_builder`](https://docs.rs/derive_builder). This crate was designed with many lessons learned from them.

See [alternatives](https://bon-rs.com/guide/alternatives) for comparison.

## Supporters

Big thanks to `bon`'s current financial supporters ❤️

**Ethan Skowronski**\
$1/month

**Julius Lungys**\
$1/month

## Past Supporters

Big thanks to `bon`'s past financial supporters ❤️

[![](https://github.com/user-attachments/assets/b0acb844-4b91-461c-95ae-90a601296500)](https://kindness.ai)\
[**Kindness**](https://kindness.ai)

## Who's Using `bon`?

Some notable open-source users: [`crates.io` backend](https://github.com/rust-lang/crates.io), [`tantivy`](https://github.com/quickwit-oss/tantivy), [`apache-avro`](https://github.com/apache/avro-rs), [`google-cloud-auth`](https://github.com/googleapis/google-cloud-rust), [`comrak`](https://github.com/kivikakk/comrak), [`ractor`](https://github.com/slawlor/ractor).

## Getting Help

If you can't figure something out, consult the docs and maybe use the `🔍 Search` bar on our [docs website](https://bon-rs.com). You may also create an issue or a discussion on the [Github repository](https://github.com/elastio/bon) for help or write us a message on [Discord](https://bon-rs.com/discord).

## Socials

         Discord (https://bon-rs.com/discord)
         Here you can leave feedback, ask questions, report bugs, etc.

## License

Licensed under either of Apache License, Version
2.0 (https://github.com/elastio/bon/blob/master/LICENSE-APACHE) or MIT license (https://github.com/elastio/bon/blob/master/LICENSE-MIT) at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.

