summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock35
-rw-r--r--devenv.nix6
-rw-r--r--src/lib.rs35
-rw-r--r--tests/basic.rs9
4 files changed, 59 insertions, 26 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 2e23344..c98510c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -13,7 +13,7 @@ dependencies = [
"manyhow",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -29,7 +29,7 @@ dependencies = [
"proc-macro2",
"quote",
"quote-use",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -40,13 +40,13 @@ checksum = "2550f75b8cfac212855f6b1885455df8eaee8fe8e246b647d69146142e016084"
[[package]]
name = "derive-where"
-version = "1.6.1"
+version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d08b3a0bcc0d079199cd476b2cae8435016ec11d1c0986c6901c5ac223041534"
+checksum = "2e2b94854e8576378ccda7c8de8a66ed8b4e8acbd2c50ec3418ea6c8aaf4b567"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 3.0.6",
]
[[package]]
@@ -56,7 +56,7 @@ dependencies = [
"attribute-derive",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -74,7 +74,7 @@ dependencies = [
"manyhow-macros",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -136,14 +136,14 @@ dependencies = [
"proc-macro-utils",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
name = "smallvec"
-version = "1.15.2"
+version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
+checksum = "ba467056f1b547ed52077911161fc86985becbc60e8e1857c8a144dab0def891"
[[package]]
name = "syn"
@@ -157,7 +157,18 @@ dependencies = [
]
[[package]]
+name = "syn"
+version = "3.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
name = "unicode-ident"
-version = "1.0.24"
+version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
+checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954"
diff --git a/devenv.nix b/devenv.nix
index 04cf216..e3ffe48 100644
--- a/devenv.nix
+++ b/devenv.nix
@@ -16,12 +16,6 @@ in
cargo-seek
cargo-nextest
];
- scripts.watcher = {
- exec = ''
- watchexec -c -e rs "cargo clippy && cargo test && cargo run"
- '';
- packages = [ pkgs.watchexec ];
- };
enterShell = ''
cargo update
'';
diff --git a/src/lib.rs b/src/lib.rs
index 314f813..8024048 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -293,6 +293,14 @@ pub fn derive_builder(input: TokenStream) -> TokenStream {
#builder_macro
+ impl core::convert::From<#struct_name> for #builder_name<#(#trues),*> {
+ fn from(s: #struct_name) -> Self {
+ Self {
+ #(#field_names: Some(s.#field_names),)*
+ }
+ }
+ }
+
impl<#(const #const_generics: bool),*> core::default::Default for #builder_name<#(#const_generics),*> {
fn default() -> Self {
Self {
@@ -305,6 +313,10 @@ pub fn derive_builder(input: TokenStream) -> TokenStream {
#builder_visibility fn builder() -> #builder_name<#(#falses),*> {
#builder_name::default()
}
+
+ #builder_visibility fn into_builder(self) -> #builder_name<#(#trues),*> {
+ #builder_name::from(self)
+ }
}
impl<#(const #const_generics: bool),*> #builder_name<#(#const_generics),*> {
@@ -360,17 +372,28 @@ pub fn derive_builder(input: TokenStream) -> TokenStream {
pub fn build(input: TokenStream) -> TokenStream {
let structure = parse_macro_input!(input as ExprStruct);
let struct_name = &structure.path;
+ let base = &structure.rest;
let field_names = structure.fields.iter().map(|field| &field.member);
let field_values = structure.fields.iter().map(|field| &field.expr);
- quote! {
- #struct_name
- ::builder()
- #(.#field_names(#field_values))*
- .build()
+ if let Some(base) = base {
+ quote! {
+ #base
+ .into_builder()
+ #(.#field_names(#field_values))*
+ .build()
+ }
+ .into()
+ } else {
+ quote! {
+ #struct_name
+ ::builder()
+ #(.#field_names(#field_values))*
+ .build()
+ }
+ .into()
}
- .into()
}
/// Creates a declarative macro to construct a type that derives [`Builder`]
diff --git a/tests/basic.rs b/tests/basic.rs
index ce3abf8..52212d0 100644
--- a/tests/basic.rs
+++ b/tests/basic.rs
@@ -16,6 +16,8 @@ mod foo {
use foo::Foo;
+use crate::foo::FooBuild;
+
fn main() {
let x = Foo::builder().baz(42).bar("hello").bat(5).build();
assert_eq!(
@@ -27,8 +29,11 @@ fn main() {
}
);
- let bar = "hello";
- let _: Foo = Foo! { bar };
+ let x: Foo = Foo! {
+ baz: 32,
+ bat: 64,
+ ..x
+ };
assert_eq!(
x,
Foo {