Repository: BrynCooke/buildstructor (language: rust)

Issue:
Add Into support for Option and all simple types
Like the collection support Into can be used for all simple types and options. 


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5d9cc68..690266e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,11 @@ All notable changes to this project will be documented in this file.
 
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## 0.1.9 - unreleased
+[#24](https://github.com/BrynCooke/buildstructor/issues/24)
+Simple types are now given Into treatment globally.
+
 ## 0.1.8 - 2022-04-25
 [#5](https://github.com/BrynCooke/buildstructor/issues/5)
 Simple types are now given Into treatment when inserting to collection via singular form.  
diff --git a/README.md b/README.md
index 4677331..4ffa9d5 100644
--- a/README.md
+++ b/README.md
@@ -123,7 +123,16 @@ fn main() {
 
 ### Into field
 
-You can use generics as usual in your constructor.
+#### Simple types
+Types automatically have into conversion if:
+* the type is not a scalar.
+* the type has no generic parameters. (this may be relaxed later)
+* the type is a generic parameter from the impl or constructor method.
+
+This is useful for Strings, but also other types where you want to overload the singular build method. Create an enum that derives From for all the types you want to support and then use this type in your constructor.
+
+#### Complex types
+You can use generics as usual in your constructor. However, this has the downside of not being able to support optional fields.
 
 ```rust
 use buildstructor::builder;
@@ -252,7 +261,7 @@ In the case that a singular form cannot be derived automatically the suffix `_en
 
 Adding a singular entry will automatically perform an into conversion if:
 * the type is not a scalar.
-* the type has no generic paramaters. (this may be relaxed later)
+* the type has no generic parameters. (this may be relaxed later)
 * the type is a generic parameter from the impl or constructor method. 
 
 This is useful for Strings, but also other types where you want to overload the singular build method. Create an enum that derives From for all the types you want to support and then use this type in your constructor.
diff --git a/src/buildstructor/codegen.rs b/src/buildstructor/codegen.rs
index ed375e8..6f121f1 100644
--- a/src/buildstructor/codegen.rs
+++ b/src/buildstructor/codegen.rs
@@ -165,23 +165,34 @@ pub fn builder_methods(
 
             let set = call(format_ident!("__set"), vec![Expr::Path(field_name.to_expr_path())]);
             let new_state = params(ir, idx, field_name, &builder_type_generics, set);
-            let set_some = call(format_ident!("__set"), vec![call(format_ident!("Some"), vec![Expr::Path(field_name.to_expr_path())])]);
-            let new_state_option = params(ir, idx, field_name, &builder_type_generics, set_some);
             let builder_type_generics = Generics::combine(vec![&builder_type_generics.without(idx), &builder_generics]);
-            let generic_param = ty.generic_args();
 
             match f.field_type {
                 FieldType::Option => {
                     let and_method_name = format_ident!("and_{}", f.name);
+                    let mut field_collection_type = f.generic_type.clone();
+                    let mut into_generics = None;
+                    let mut into_call = None;
+                    if f.generic_into {
+                        let into_type = field_collection_type.replace(Type::parse("__T"));
+                        let _ = into_generics.insert(Some(quote! {
+                            <__T: Into<#into_type>>
+                        }));
+                        into_call = Some(quote!{
+                            .into()
+                        })
+                    }
                     quote! {
                         impl #builder_type_generics #builder_name #before {
-                            pub fn #method_name (self, #field_name: #generic_param) -> #builder_name #after #builder_where_clause {
+                            pub fn #method_name #into_generics(self, #field_name: #field_collection_type) -> #builder_name #after #builder_where_clause {
+                                let #field_name = Some(#field_name #into_call);
                                 #builder_name {
-                                    fields: #new_state_option,
+                                    fields: #new_state,
                                     _phantom: core::default::Default::default()
                                 }
                             }
-                            pub fn #and_method_name (self, #field_name: #ty) -> #builder_name #after #builder_where_clause {
+                            pub fn #and_method_name #into_generics(self, #field_name: Option<#field_collection_type>) -> #builder_name #after #builder_where_clause {
+                                let #field_name = #field_name.map(|v|v #into_call);
                                 #builder_name {
                                     fields: #new_state,
                                     _phantom: core::default::Default::default()
@@ -192,10 +203,10 @@ pub fn builder_methods(
                 },
                 FieldType::Set => {
                     let (singular, plural) = single_plural_names(field_name);
-                    let mut field_collection_type = f.collection_type.clone();
+                    let mut field_collection_type = f.generic_type.clone();
                     let mut into_generics = None;
                     let mut into_call = None;
-                    if f.collection_into {
+                    if f.generic_into {
                         let into_type = field_collection_type.replace(Type::parse("__T"));
                         let _ = into_generics.insert(Some(quote! {
                             <__T: Into<#into_type>>
@@ -223,10 +234,10 @@ pub fn builder_methods(
                 },
                 FieldType::Vec => {
                     let (singular, plural) = single_plural_names(field_name);
-                    let mut field_collection_type = f.collection_type.clone();
+                    let mut field_collection_type = f.generic_type.clone();
                     let mut into_generics = None;
                     let mut into_call = None;
-                    if f.collection_into {
+                    if f.generic_into {
                         let into_type = field_collection_type.replace(Type::parse("__T"));
                         let _ = into_generics.insert(Some(quote! {
                             <__T: Into<#into_type>>
@@ -305,12 +316,27 @@ pub fn builder_methods(
                         }
                     }
                 },
-                _ => quote! {
-                    impl #builder_type_generics #builder_name #before {
-                        pub fn #method_name (self, #field_name: #ty) -> #builder_name #after {
-                            #builder_name {
-                                fields: #new_state,
-                                _phantom: core::default::Default::default()
+                _ => {
+                    let mut into_generics = None;
+                    let mut into_call = None;
+                    let mut ty = Some(ty.clone());
+                    if f.into {
+                        let into_type = ty.replace(Type::parse("__T"));
+                        let _ = into_generics.insert(Some(quote! {
+                            <__T: Into<#into_type>>
+                        }));
+                        into_call = Some(quote!{
+                            .into()
+                        })
+                    }
+                    quote! {
+                        impl #builder_type_generics #builder_name #before {
+                            pub fn #method_name #into_generics(self, #field_name: #ty) -> #builder_name #after {
+                                let #field_name = #field_name #into_call;
+                                #builder_name {
+                                    fields: #new_state,
+                                    _phantom: core::default::Default::default()
+                                }
                             }
                         }
                     }
diff --git a/src/buildstructor/lower.rs b/src/buildstructor/lower.rs
index 4a2d8aa..15b23ae 100644
--- a/src/buildstructor/lower.rs
+++ b/src/buildstructor/lower.rs
@@ -29,13 +29,14 @@ pub struct Ir {
 pub struct BuilderField {
     pub name: Ident,
     pub ty: Type,
+    pub into: bool,
     pub field_type: FieldType,
     pub key_type: Option<Type>,
     pub key_into: bool,
     pub value_type: Option<Type>,
     pub value_into: bool,
-    pub collection_type: Option<Type>,
-    pub collection_into: bool,
+    pub generic_type: Option<Type>,
+    pub generic_into: bool,
 }
 
 #[derive(Debug)]
@@ -88,56 +89,56 @@ fn builder_fields(model: &ConstrutorModel) -> Vec<BuilderField> {
                 let ident = try_match!(&*t.pat, Pat::Ident(x)=>x).ok()?;
                 let field_type = field_type(&*t.ty);
                 let args = t.ty.generic_args();
-                let (
-                    (key_type, key_into),
-                    (value_type, value_into),
-                    (collection_type, collection_into),
-                ) = match (
-                    &field_type,
-                    args.and_then(|args| args.iter().next()),
-                    args.and_then(|args| args.iter().nth(1)),
-                ) {
-                    (
-                        FieldType::Vec | FieldType::Set,
-                        Some(GenericArgument::Type(collection_type)),
-                        None,
-                    ) => (
-                        (None, false),
-                        (None, false),
+                let ((key_type, key_into), (value_type, value_into), (generic_type, generic_into)) =
+                    match (
+                        &field_type,
+                        args.and_then(|args| args.iter().next()),
+                        args.and_then(|args| args.iter().nth(1)),
+                    ) {
                         (
-                            Some(collection_type.clone()),
-                            collection_type
-                                .is_into_capable(&model.generics, &model.method_generics),
-                        ),
-                    ),
-                    (
-                        FieldType::Map,
-                        Some(GenericArgument::Type(key_type)),
-                        Some(GenericArgument::Type(value_type)),
-                    ) => (
-                        (
-                            Some(key_type.clone()),
-                            key_type.is_into_capable(&model.generics, &model.method_generics),
+                            FieldType::Option | FieldType::Vec | FieldType::Set,
+                            Some(GenericArgument::Type(collection_type)),
+                            None,
+                        ) => (
+                            (None, false),
+                            (None, false),
+                            (
+                                Some(collection_type.clone()),
+                                collection_type
+                                    .is_into_capable(&model.generics, &model.method_generics),
+                            ),
                         ),
                         (
-                            Some(value_type.clone()),
-                            value_type.is_into_capable(&model.generics, &model.method_generics),
+                            FieldType::Map,
+                            Some(GenericArgument::Type(key_type)),
+                            Some(GenericArgument::Type(value_type)),
+                        ) => (
+                            (
+                                Some(key_type.clone()),
+                                key_type.is_into_capable(&model.generics, &model.method_generics),
+                            ),
+                            (
+                                Some(value_type.clone()),
+                                value_type.is_into_capable(&model.generics, &model.method_generics),
+                            ),
+                            (None, false),
                         ),
-                        (None, false),
-                    ),
-                    _ => ((None, false), (None, false), (None, false)),
-                };
+                        _ => ((None, false), (None, false), (None, false)),
+                    };
 
+                let into =
+                    t.ty.is_into_capable(&model.generics, &model.method_generics);
                 Some(BuilderField {
                     ty: *t.ty.clone(),
+                    into,
                     name: ident.ident.clone(),
                     field_type,
                     key_type,
                     key_into,
                     value_type,
                     value_into,
-                    collection_type,
-                    collection_into,
+                    generic_type,
+                    generic_into,
                 })
             }
             FnArg::Receiver(_) => None,
diff --git a/src/buildstructor/utils.rs b/src/buildstructor/utils.rs
index 3b46a40..e05e38f 100644
--- a/src/buildstructor/utils.rs
+++ b/src/buildstructor/utils.rs
@@ -194,7 +194,7 @@ pub trait TypeExt {
     fn wrap_in_generic_with_module(&self, module: &Ident, ident: Ident) -> Type;
     fn to_path(&self) -> Option<Path>;
     fn parse(name: &'static str) -> Type;
-    fn is_into_capable(&self, impl_geneerics: &Generics, constructor_geneerics: &Generics) -> bool;
+    fn is_into_capable(&self, impl_generics: &Generics, constructor_generics: &Generics) -> bool;
 }
 
 impl TypeExt for Type {
@@ -283,7 +283,7 @@ impl TypeExt for Type {
         })
     }
 
-    fn is_into_capable(&self, impl_geneerics: &Generics, constructor_geneerics: &Generics) -> bool {
+    fn is_into_capable(&self, impl_generics: &Generics, constructor_generics: &Generics) -> bool {
         // This is super restrictive for now. No generic types. No scalars, No tuples.
         // The goal is to allow users to provide their own intermediate enum type or to use strings/&str.
         // Maybe this can be relaxed a little in future.
@@ -307,10 +307,10 @@ impl TypeExt for Type {
             }
         }
         // If this is a generic type we can't really use Into as the user will have to specify the type on the builder.
-        for p in impl_geneerics
+        for p in impl_generics
             .params
             .iter()
-            .chain(constructor_geneerics.params.iter())
+            .chain(constructor_generics.params.iter())
         {
             if let GenericParam::Type(ty) = p {
                 if Some(&ty.ident) == ident.as_ref() {
diff --git a/src/lib.rs b/src/lib.rs
index 42fea0f..d17ca40 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -23,7 +23,7 @@ use crate::buildstructor::parse;
 /// ```rust
 /// use buildstructor::builder;
 ///
-/// pub struct MyStruct {
+/// struct MyStruct {
 ///     sum: usize,
 /// }
 ///


Test patch:
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__async_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__async_test.snap
index c1b42d3..e3b3f55 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__async_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__async_test.snap
@@ -50,6 +50,7 @@ mod __foo_new_builder {
     }
     impl __FooBuilder<(__Required<usize>,)> {
         pub fn simple(self, simple: usize) -> __FooBuilder<(__Set<usize>,)> {
+            let simple = simple;
             __FooBuilder {
                 fields: (__set(simple),),
                 _phantom: core::default::Default::default(),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_test.snap
index 03e9f6c..a89de53 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_test.snap
@@ -82,6 +82,7 @@ mod __foo_new_builder {
             self,
             simple: usize,
         ) -> __FooBuilder<(__Set<usize>, __1, __2, __3, __4, __5)> {
+            let simple = simple;
             __FooBuilder {
                 fields: (
                     __set(simple),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__fallible_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__fallible_test.snap
index 24a5b76..598c60e 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__fallible_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__fallible_test.snap
@@ -50,6 +50,7 @@ mod __foo_new_builder {
     }
     impl __FooBuilder<(__Required<usize>,)> {
         pub fn simple(self, simple: usize) -> __FooBuilder<(__Set<usize>,)> {
+            let simple = simple;
             __FooBuilder {
                 fields: (__set(simple),),
                 _phantom: core::default::Default::default(),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__generic_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__generic_test.snap
index 8b07a8e..8d4e959 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__generic_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__generic_test.snap
@@ -51,6 +51,7 @@ mod __foo_new_builder {
     }
     impl<T> __FooBuilder<(__Required<T>,), T> {
         pub fn simple(self, simple: T) -> __FooBuilder<(__Set<T>,), T> {
+            let simple = simple;
             __FooBuilder {
                 fields: (__set(simple),),
                 _phantom: core::default::Default::default(),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_test.snap
index 4fb37b3..629e63c 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_test.snap
@@ -54,6 +54,7 @@ mod __foo_new_builder {
     }
     impl<T: Into<String>> __FooBuilder<(__Required<T>,), T> {
         pub fn simple(self, simple: T) -> __FooBuilder<(__Set<T>,), T> {
+            let simple = simple;
             __FooBuilder {
                 fields: (__set(simple),),
                 _phantom: core::default::Default::default(),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_where_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_where_test.snap
index c27362a..273a94d 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_where_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_where_test.snap
@@ -51,6 +51,7 @@ mod __foo_new_builder {
     }
     impl<T> __FooBuilder<(__Required<T>,), T> {
         pub fn simple(self, simple: T) -> __FooBuilder<(__Set<T>,), T> {
+            let simple = simple;
             __FooBuilder {
                 fields: (__set(simple),),
                 _phantom: core::default::Default::default(),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multi_field_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multi_field_test.snap
index ca266cf..2b07fd4 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multi_field_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multi_field_test.snap
@@ -52,6 +52,7 @@ mod __foo_new_builder {
     }
     impl<__1> __FooBuilder<(__Required<usize>, __1)> {
         pub fn simple(self, simple: usize) -> __FooBuilder<(__Set<usize>, __1)> {
+            let simple = simple;
             __FooBuilder {
                 fields: (__set(simple), self.fields.1),
                 _phantom: core::default::Default::default(),
@@ -60,6 +61,7 @@ mod __foo_new_builder {
     }
     impl<__0> __FooBuilder<(__0, __Required<usize>)> {
         pub fn simple2(self, simple2: usize) -> __FooBuilder<(__0, __Set<usize>)> {
+            let simple2 = simple2;
             __FooBuilder {
                 fields: (self.fields.0, __set(simple2)),
                 _phantom: core::default::Default::default(),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multiple_generics_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multiple_generics_test.snap
index bf7798e..6d5ad86 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multiple_generics_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multiple_generics_test.snap
@@ -121,9 +121,9 @@ mod __request_fake_new_builder {
         K,
         V,
     > __RequestBuilder<(__0, __Optional<Option<http::Uri>>, __2, __3), T, K, V> {
-        pub fn uri(
+        pub fn uri<__T: Into<http::Uri>>(
             self,
-            uri: http::Uri,
+            uri: __T,
         ) -> __RequestBuilder<(__0, __Set<Option<http::Uri>>, __2, __3), T, K, V>
         where
             HeaderName: TryFrom<K>,
@@ -131,14 +131,15 @@ mod __request_fake_new_builder {
             HeaderValue: TryFrom<V>,
             <HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
         {
+            let uri = Some(uri.into());
             __RequestBuilder {
-                fields: (self.fields.0, __set(Some(uri)), self.fields.2, self.fields.3),
+                fields: (self.fields.0, __set(uri), self.fields.2, self.fields.3),
                 _phantom: core::default::Default::default(),
             }
         }
-        pub fn and_uri(
+        pub fn and_uri<__T: Into<http::Uri>>(
             self,
-            uri: Option<http::Uri>,
+            uri: Option<__T>,
         ) -> __RequestBuilder<(__0, __Set<Option<http::Uri>>, __2, __3), T, K, V>
         where
             HeaderName: TryFrom<K>,
@@ -146,6 +147,7 @@ mod __request_fake_new_builder {
             HeaderValue: TryFrom<V>,
             <HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
         {
+            let uri = uri.map(|v| v.into());
             __RequestBuilder {
                 fields: (self.fields.0, __set(uri), self.fields.2, self.fields.3),
                 _phantom: core::default::Default::default(),
@@ -160,9 +162,9 @@ mod __request_fake_new_builder {
         K,
         V,
     > __RequestBuilder<(__0, __1, __Optional<Option<http::Method>>, __3), T, K, V> {
-        pub fn method(
+        pub fn method<__T: Into<http::Method>>(
             self,
-            method: http::Method,
+            method: __T,
         ) -> __RequestBuilder<(__0, __1, __Set<Option<http::Method>>, __3), T, K, V>
         where
             HeaderName: TryFrom<K>,
@@ -170,19 +172,15 @@ mod __request_fake_new_builder {
             HeaderValue: TryFrom<V>,
             <HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
         {
+            let method = Some(method.into());
             __RequestBuilder {
-                fields: (
-                    self.fields.0,
-                    self.fields.1,
-                    __set(Some(method)),
-                    self.fields.3,
-                ),
+                fields: (self.fields.0, self.fields.1, __set(method), self.fields.3),
                 _phantom: core::default::Default::default(),
             }
         }
-        pub fn and_method(
+        pub fn and_method<__T: Into<http::Method>>(
             self,
-            method: Option<http::Method>,
+            method: Option<__T>,
         ) -> __RequestBuilder<(__0, __1, __Set<Option<http::Method>>, __3), T, K, V>
         where
             HeaderName: TryFrom<K>,
@@ -190,6 +188,7 @@ mod __request_fake_new_builder {
             HeaderValue: TryFrom<V>,
             <HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
         {
+            let method = method.map(|v| v.into());
             __RequestBuilder {
                 fields: (self.fields.0, self.fields.1, __set(method), self.fields.3),
                 _phantom: core::default::Default::default(),
@@ -208,6 +207,7 @@ mod __request_fake_new_builder {
             self,
             body: T,
         ) -> __RequestBuilder<(__0, __1, __2, __Set<T>), T, K, V> {
+            let body = body;
             __RequestBuilder {
                 fields: (self.fields.0, self.fields.1, self.fields.2, __set(body)),
                 _phantom: core::default::Default::default(),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__option_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__option_test.snap
index 0243032..d4d0f18 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__option_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__option_test.snap
@@ -50,8 +50,9 @@ mod __foo_new_builder {
     }
     impl __FooBuilder<(__Optional<Option<usize>>,)> {
         pub fn option(self, option: usize) -> __FooBuilder<(__Set<Option<usize>>,)> {
+            let option = Some(option);
             __FooBuilder {
-                fields: (__set(Some(option)),),
+                fields: (__set(option),),
                 _phantom: core::default::Default::default(),
             }
         }
@@ -59,6 +60,7 @@ mod __foo_new_builder {
             self,
             option: Option<usize>,
         ) -> __FooBuilder<(__Set<Option<usize>>,)> {
+            let option = option.map(|v| v);
             __FooBuilder {
                 fields: (__set(option),),
                 _phantom: core::default::Default::default(),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__pub_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__pub_test.snap
index 3036664..df20239 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__pub_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__pub_test.snap
@@ -50,6 +50,7 @@ mod __foo_new_builder {
     }
     impl __FooBuilder<(__Required<usize>,)> {
         pub fn simple(self, simple: usize) -> __FooBuilder<(__Set<usize>,)> {
+            let simple = simple;
             __FooBuilder {
                 fields: (__set(simple),),
                 _phantom: core::default::Default::default(),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__returns_self_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__returns_self_test.snap
index c777fd5..923cdf4 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__returns_self_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__returns_self_test.snap
@@ -50,6 +50,7 @@ mod __foo_new_builder {
     }
     impl __FooBuilder<(__Required<usize>,)> {
         pub fn simple(self, simple: usize) -> __FooBuilder<(__Set<usize>,)> {
+            let simple = simple;
             __FooBuilder {
                 fields: (__set(simple),),
                 _phantom: core::default::Default::default(),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__single_field_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__single_field_test.snap
index c777fd5..923cdf4 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__single_field_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__single_field_test.snap
@@ -50,6 +50,7 @@ mod __foo_new_builder {
     }
     impl __FooBuilder<(__Required<usize>,)> {
         pub fn simple(self, simple: usize) -> __FooBuilder<(__Set<usize>,)> {
+            let simple = simple;
             __FooBuilder {
                 fields: (__set(simple),),
                 _phantom: core::default::Default::default(),
diff --git a/tests/buildstructor/pass/option_field.rs b/tests/buildstructor/pass/option_field.rs
index 0c68f59..d3d97bc 100644
--- a/tests/buildstructor/pass/option_field.rs
+++ b/tests/buildstructor/pass/option_field.rs
@@ -1,17 +1,19 @@
 use buildstructor::builder;
 pub struct Foo {
-    simple: Option<usize>,
+    simple: Option<String>,
 }
 
 #[builder]
 impl Foo {
-    fn new(simple: Option<usize>) -> Foo {
+    fn new(simple: Option<String>) -> Foo {
         Self { simple }
     }
 }
 
 fn main() {
-    let _ = Foo::builder().simple(3).build();
-    let _ = Foo::builder().and_simple(Some(3)).build();
+    let _ = Foo::builder().simple("3").build();
+    let _ = Foo::builder().simple("3".to_string()).build();
+    let _ = Foo::builder().and_simple(Some("3")).build();
+    let _ = Foo::builder().and_simple(Some("3".to_string())).build();
     let _ = Foo::builder().build();
 }
diff --git a/tests/buildstructor/pass/single_field.rs b/tests/buildstructor/pass/single_field.rs
index 9cdeeae..b7d59db 100644
--- a/tests/buildstructor/pass/single_field.rs
+++ b/tests/buildstructor/pass/single_field.rs
@@ -1,15 +1,16 @@
 use buildstructor::builder;
 pub struct Foo {
-    simple: usize,
+    simple: String,
 }
 
 #[builder]
 impl Foo {
-    fn new(simple: usize) -> Foo {
+    fn new(simple: String) -> Foo {
         Self { simple }
     }
 }
 
 fn main() {
-    let _ = Foo::builder().simple(3).build();
+    let _ = Foo::builder().simple("3").build();
+    let _ = Foo::builder().simple("3".to_string()).build();
 }