Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace.package]
edition = "2021"
version = "0.5.0"
version = "0.5.2"
authors = ["Oliver Tale-Yazdi <[email protected]>"]
license = "GPL-3.0-only"
repository = "https://github.com/ggwpez/typesafe-builders"
Expand All @@ -24,7 +24,7 @@ typesafe-builders-core = { path = "typesafe-builders-core", version = "0.5.0" }
typesafe-builders-derive = { path = "typesafe-builders-derive", version = "0.5.0" }

# External deps
derive-syn-parse = { version = "0.1.5", default-features = false }
proc-macro2 = { version = "1.0.56", default-features = false }
quote = { version = "1.0.26", default-features = false }
syn = "2.0.15"
derive-syn-parse = { version = "0.2.0", default-features = false }
proc-macro2 = { version = "1.0.101", default-features = false }
quote = { version = "1.0.40", default-features = false }
syn = "2.0.106"
6 changes: 3 additions & 3 deletions MAINTAIN
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Without any un-staged changes:

```bash
git tag -s -f typesafe-builders@0.4.1 -m "typesafe-builders v0.4.1"
git tag -s -f typesafe-builders-core@0.4.1 -m "typesafe-builders-core v0.4.1"
git tag -s -f typesafe-builders-derive@0.4.1 -m "typesafe-builders-derive v0.4.1"
git tag -s -f typesafe-builders@0.5.1 -m "typesafe-builders v0.5.1"
git tag -s -f typesafe-builders-core@0.5.1 -m "typesafe-builders-core v0.5.1"
git tag -s -f typesafe-builders-derive@0.5.1 -m "typesafe-builders-derive v0.5.1"

cargo publish -p typesafe-builders-core && cargo publish -p typesafe-builders-derive && cargo publish -p typesafe-builders
```
75 changes: 31 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,27 @@ No more worrying whether the `build` call on your builder will return `Ok` or no
```rust
use typesafe_builders::prelude::*;

fn main() {
#[derive(Builder)]
struct Point {
#[builder(constructor)]
x: u8,
y: u8,
#[builder(optional)]
z: Option<u8>,
}
#[derive(Builder)]
struct Point {
#[builder(constructor)]
x: u8,
y: u8,
#[builder(optional)]
z: Option<u8>,
}

// `builder` requires `x` since it is marked as `constructor`.
let builder = Point::builder(1);
// These do not compile:
// partial.x(6); // `x` is already set
// partial.build(); // `y` is not set
// `builder` requires `x` since it is marked as `constructor`.
let builder = Point::builder(1);
// These do not compile:
// partial.x(6); // `x` is already set
// partial.build(); // `y` is not set

// `build` is only available once all required fields are set:
let result = builder.y(2).build();
// `build` is only available once all required fields are set:
let result = builder.y(2).build();

assert_eq!(result.x, 1);
assert_eq!(result.y, 2);
assert_eq!(result.z, None);
}
assert_eq!(result.x, 1);
assert_eq!(result.y, 2);
assert_eq!(result.z, None);
```


Expand Down Expand Up @@ -97,12 +95,10 @@ pub struct Struct {
x: u8,
}

fn main() {
// without x
Struct::builder().build();
// with x
Struct::builder().x(4).build();
}
// without x
Struct::builder().build();
// with x
Struct::builder().x(4).build();
```

### Constructor
Expand All @@ -118,11 +114,10 @@ pub struct Struct {
x: u8,
}

fn main() {
Struct::builder(4).build();
// does not work:
// Struct::builder(4).x(5).build();
}
Struct::builder(4).build();

// This does not compile since `x` is already set:
// Struct::builder(4).x(5).build();
```

### Decay
Expand All @@ -138,10 +133,8 @@ pub struct Struct {
x: Option<u8>,
}

fn main() {
// Use `4` instead of `Some(4)`
Struct::builder().x(4).build();
}
// You can use `4` now instead of `Some(4)`:
Struct::builder().x(4).build();
```

# How does it work?
Expand Down Expand Up @@ -188,9 +181,7 @@ pub struct Struct<'a, 'b, 'c> {
x: &'a Box<&'b Option<&'c str>>, // yikes
}

fn main() {
Struct::builder().x(&Box::new(&Some("hi"))).build();
}
Struct::builder().x(&Box::new(&Some("hi"))).build();
```

### Generics
Expand All @@ -207,9 +198,7 @@ mod other {
}
}

fn main() {
other::Struct::<u8>::builder().y(Some(4)).build();
}
other::Struct::<u8>::builder().y(Some(4)).build();
```

### Const Generics
Expand All @@ -226,9 +215,7 @@ mod other {
}
}

fn main() {
other::Struct::<1>::builder().x([1]).build();
}
other::Struct::<1>::builder().x([1]).build();
```

# TODOs
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[toolchain]
channel = "nightly-2023-05-04"
channel = "nightly-2025-09-01"
components = [ "rustfmt", "clippy" ]
profile = "minimal"
7 changes: 2 additions & 5 deletions typesafe-builders-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,8 @@ struct ParsedFieldAttr {

pub fn impl_derive_builder(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
let syn::Data::Struct(ref s) = ast.data else {
return Err(syn::Error::new_spanned(
ast,
"derive(Builder) can only be used on structs",
));
};
return Err(syn::Error::new_spanned(ast, "derive(Builder) can only be used on structs"));
};
let mut user_generics_def = Vec::<&syn::GenericParam>::new();
let mut user_generics_impl = Vec::<proc_macro2::TokenStream>::new();
let mut user_generics_alias = Vec::<proc_macro2::TokenStream>::new();
Expand Down
2 changes: 1 addition & 1 deletion typesafe-builders/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ typesafe-builders-core.workspace = true
typesafe-builders-derive.workspace = true

[dev-dependencies]
trybuild = "1.0.80"
trybuild = "1.0.90"
2 changes: 1 addition & 1 deletion typesafe-builders/tests/ui/reject/builder_priv.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ error[E0603]: struct `Struct` is private
note: the struct `Struct` is defined here
--> tests/ui/reject/builder_priv.rs:5:2
|
5 | struct Struct {
5 | struct Struct {
| ^^^^^^^^^^^^^
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> tests/ui/reject/field_attr/ctor/missing_arg.rs:10:2
|
10 | Struct::builder().build();
| ^^^^^^^^^^^^^^^-- an argument of type `u8` is missing
| ^^^^^^^^^^^^^^^-- argument #1 of type `u8` is missing
|
note: associated function defined here
--> tests/ui/reject/field_attr/ctor/missing_arg.rs:3:10
|
3 | #[derive(Builder)]
3 | #[derive(Builder)]
| ^^^^^^^
...
6 | x: u8,
6 | x: u8,
| -----
= note: this error originates in the derive macro `Builder` (in Nightly builds, run with -Z macro-backtrace for more info)
help: provide the argument
|
10 | Struct::builder(/* u8 */).build();
| ~~~~~~~~~~
| ++++++++
4 changes: 2 additions & 2 deletions typesafe-builders/tests/ui/reject/field_missing_required_2.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use typesafe_builders::prelude::*;

//! `Option` is *not* treated as optional.

use typesafe_builders::prelude::*;

#[derive(Builder)]
struct Struct {
x: Option<u8>,
Expand Down
22 changes: 3 additions & 19 deletions typesafe-builders/tests/ui/reject/field_missing_required_2.stderr
Original file line number Diff line number Diff line change
@@ -1,23 +1,7 @@
error[E0753]: expected outer doc comment
--> tests/ui/reject/field_missing_required_2.rs:3:1
|
3 | //! `Option` is *not* treated as optional.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
6 | / struct Struct {
7 | | x: Option<u8>,
8 | | }
| |_- the inner doc comment doesn't annotate this struct
|
help: to annotate the struct, change the doc comment from inner to outer style
|
3 | /// `Option` is *not* treated as optional.
| ~

error[E0599]: no method named `build` found for struct `GenericStructBuilder<false>` in the current scope
--> tests/ui/reject/field_missing_required_2.rs:11:20
|
5 | #[derive(Builder)]
--> tests/ui/reject/field_missing_required_2.rs:11:20
|
5 | #[derive(Builder)]
| ------- method `build` not found for this struct
...
11 | Struct::builder().build();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
error[E0599]: no method named `x` found for struct `GenericStructBuilder<true>` in the current scope
--> tests/ui/reject/field_set_constructor.rs:10:29
|
3 | #[derive(Builder)]
--> tests/ui/reject/field_set_constructor.rs:10:29
|
3 | #[derive(Builder)]
| ------- method `x` not found for this struct
...
10 | let r = Struct::builder(2).x(3).build();
Expand Down
Loading