Skip to content

Commit 8e3be32

Browse files
committed
Add non-wrapping setter for Option (#34)
1 parent e752546 commit 8e3be32

File tree

7 files changed

+383
-33
lines changed

7 files changed

+383
-33
lines changed

macon_derive/src/generators/result_panic.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -58,34 +58,41 @@ impl ResultPanicGenerator {
5858
let setter = f.setter();
5959
let typevar = f.typevar();
6060
let ident = &f.ident;
61+
let ty = f.ty_into();
62+
let argtype = if ! f.into.is_disabled() {
63+
typevar.to_token_stream()
64+
} else {
65+
ty.to_token_stream()
66+
};
67+
let generic = if ! f.into.is_disabled() {
68+
quote!(#typevar: ::core::convert::Into<#ty>)
69+
} else {
70+
quote!()
71+
};
6172
let setter_standard = {
6273
let assign_standard = f.result_assign(Setter::Standard);
63-
let ty = f.ty_into();
64-
let argtype = if ! f.into.is_disabled() {
65-
typevar.to_token_stream()
66-
} else {
67-
ty.to_token_stream()
68-
};
69-
let generic = if ! f.into.is_disabled() {
70-
quote!(#typevar: ::core::convert::Into<#ty>)
71-
} else {
72-
quote!()
73-
};
7474
quote! {
7575
pub fn #setter<#generic>(mut self, #ident: #argtype) -> Self {
7676
#assign_standard
7777
self
7878
}
7979
}
8080
};
81-
let setter_none = if f.option.is_enabled() {
81+
let setter_option = if f.option.is_enabled() {
8282
let setter_none = f.setter_none();
8383
let assign_none = f.result_assign(Setter::None);
84+
let setter_optional = f.setter_optional();
85+
let assign_optional= f.result_assign(Setter::Optional);
8486
quote! {
8587
pub fn #setter_none(mut self) -> Self {
8688
#assign_none
8789
self
8890
}
91+
92+
pub fn #setter_optional<#generic>(mut self, #ident: ::core::option::Option<#argtype>) -> Self {
93+
#assign_optional
94+
self
95+
}
8996
}
9097
} else {
9198
quote!()
@@ -116,7 +123,7 @@ impl ResultPanicGenerator {
116123
};
117124
quote! {
118125
#setter_standard
119-
#setter_none
126+
#setter_option
120127
#setter_keep
121128
#setter_default
122129
}

macon_derive/src/generators/typestate.rs

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -78,35 +78,48 @@ impl StateGenerator {
7878
let struct_state_from = self.properties().typestate_state(field, false, false);
7979
let struct_state_to = self.properties().typestate_state(field, false, true);
8080

81+
82+
let ident = &field.ident;
83+
let into_type = field.ty_into();
84+
let argtype = if ! field.into.is_disabled() {
85+
field.typevar().to_token_stream()
86+
} else {
87+
field.ty.to_token_stream()
88+
};
89+
let generic = if ! field.into.is_disabled() {
90+
quote!(<#argtype: ::core::convert::Into<#into_type>>)
91+
} else {
92+
quote!()
93+
};
94+
8195
let setter_standard = {
8296
let setter_standard = field.setter();
83-
let argtype = if ! field.into.is_disabled() {
84-
field.typevar().to_token_stream()
85-
} else {
86-
field.ty.to_token_stream()
87-
};
88-
let ident = &field.ident;
89-
let into_type = field.ty_into();
9097
let fields_standard = self.properties().typestate_assign(field, Setter::Standard);
91-
let generic = if ! field.into.is_disabled() {
92-
quote!(<#argtype: ::core::convert::Into<#into_type>>)
93-
} else {
94-
quote!()
95-
};
9698
quote! {
9799
pub fn #setter_standard #generic(self, #ident: #argtype) -> #builder_name<#struct_state_to> {
98100
#builder_name #fields_standard
99101
}
100102
}
101103
};
102104

103-
let setter_none = if field.option.is_enabled() {
105+
let setter_option = if field.option.is_enabled() {
104106
let setter_none = field.setter_none();
105107
let fields_none = self.properties().typestate_assign(field, Setter::None);
108+
let setter_optional = field.setter_optional();
109+
let generic = if ! field.into.is_disabled() {
110+
quote!(<#argtype: ::core::convert::Into<#into_type>>)
111+
} else {
112+
quote!()
113+
};
114+
let fields_optional = self.properties().typestate_assign(field, Setter::Optional);
106115
quote! {
107116
pub fn #setter_none(self) -> #builder_name<#struct_state_to> {
108117
#builder_name #fields_none
109118
}
119+
120+
pub fn #setter_optional #generic(self, #ident: ::core::option::Option<#argtype>) -> #builder_name<#struct_state_to> {
121+
#builder_name #fields_optional
122+
}
110123
}
111124
} else {
112125
quote!()
@@ -136,31 +149,35 @@ impl StateGenerator {
136149
let mut impl_setter = quote! {
137150
impl<#impl_state> #builder_name<#struct_state_from> {
138151
#setter_standard
139-
#setter_none
152+
#setter_option
140153
#setter_keep
141154
#setter_default
142155
}
143156
};
144157
if self.builder.is_tuple {
145158
let struct_state_from_ordered = self.properties().typestate_state(field, true, false);
146159
let struct_state_to_ordered = self.properties().typestate_state(field, true, true);
160+
let typevar = field.typevar();
161+
let into_type = field.ty_into();
162+
let ident = &field.ident;
147163
let setter_standard_ordered = {
148164
let setter_standard = field.setter();
149-
let typevar = field.typevar();
150-
let ident = &field.ident;
151-
let into_type = field.ty_into();
152165
quote! {
153166
pub fn set<#typevar: ::core::convert::Into<#into_type>>(self, #ident: #typevar) -> #builder_name<#struct_state_to_ordered> {
154167
self.#setter_standard(#ident)
155168
}
156169
}
157170
};
158-
let setter_none_ordered = if field.option.is_enabled() {
171+
let setter_option_ordered = if field.option.is_enabled() {
159172
let setter_none = field.setter_none();
173+
let setter_optional = field.setter_optional();
160174
quote! {
161175
pub fn none(self) -> #builder_name<#struct_state_to_ordered> {
162176
self.#setter_none()
163177
}
178+
pub fn set_optional<#typevar: ::core::convert::Into<#into_type>>(self, #ident: ::core::option::Option<#typevar>) -> #builder_name<#struct_state_to_ordered> {
179+
self.#setter_optional(#ident)
180+
}
164181
}
165182
} else {
166183
quote!()
@@ -190,7 +207,7 @@ impl StateGenerator {
190207

191208
impl #builder_name<#struct_state_from_ordered> {
192209
#setter_standard_ordered
193-
#setter_none_ordered
210+
#setter_option_ordered
194211
#setter_keep_ordered
195212
#setter_default_ordered
196213
}

macon_derive/src/model.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ pub enum Setter {
6464
None,
6565
Keep,
6666
Default,
67+
Optional,
6768
}
6869

6970
#[derive(Debug,Default)]
@@ -345,6 +346,9 @@ impl Property {
345346
pub fn setter_none(&self) -> Ident {
346347
format_ident!("{}_none", self.setter())
347348
}
349+
pub fn setter_optional(&self) -> Ident {
350+
format_ident!("{}_optional", self.setter())
351+
}
348352

349353
pub fn setter_keep(&self) -> Ident {
350354
format_ident!("{}_keep", self.setter())
@@ -486,6 +490,20 @@ impl Property {
486490
}
487491
value
488492
},
493+
Setter::Optional => {
494+
let mut value = if ! self.into.is_disabled() {
495+
quote!(#ident.map(::core::convert::Into::into))
496+
} else {
497+
quote!(#ident)
498+
};
499+
if self.default.is_enabled() {
500+
value = quote!(::macon::Defaulting::Set(#value));
501+
}
502+
if self.struct_default.is_enabled() {
503+
value = quote!(::macon::Keeping::Set(#value));
504+
}
505+
value
506+
}
489507
}
490508
} else {
491509
let id = self.id();
@@ -555,6 +573,13 @@ impl Property {
555573
Setter::None => quote!(::core::option::Option::None),
556574
Setter::Keep => quote!(::macon::Keeping::Keep),
557575
Setter::Default => quote!(::macon::Defaulting::Default),
576+
Setter::Optional => {
577+
let mut value = quote!(#ident);
578+
if ! self.into.is_disabled() {
579+
value = quote!(#value.map(::core::convert::Into::into));
580+
}
581+
value
582+
},
558583
};
559584
if ! self.is_required() {
560585
if setter != Setter::Keep {

tests/blueprint_panic_option.rs

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ impl NamedBuilder {
4141
self
4242
}
4343

44+
pub fn option_optional<OPTION: ::core::convert::Into<PathBuf>>(mut self, option: ::core::option::Option<OPTION>) -> NamedBuilder {
45+
self.option = option.map(::core::convert::Into::into);
46+
self
47+
}
48+
4449
pub fn option<OPTION: ::core::convert::Into<PathBuf>>(mut self, option: OPTION) -> NamedBuilder {
4550
self.option = ::core::option::Option::Some(option.into());
4651
self
@@ -107,6 +112,10 @@ impl TupleBuilder {
107112
self.1 = ::core::option::Option::None;
108113
self
109114
}
115+
pub fn set1_optional<V1: ::core::convert::Into<PathBuf>>(mut self, v1: ::core::option::Option<V1>) -> TupleBuilder {
116+
self.1 = v1.map(::core::convert::Into::into);
117+
self
118+
}
110119

111120
// impl_builder / impl_builder_build
112121
pub fn build(self) -> Tuple {
@@ -153,6 +162,21 @@ fn named_builder_build_full() {
153162
);
154163
}
155164

165+
#[test]
166+
fn named_builder_build_full_optional() {
167+
let built = Named::builder()
168+
.option_optional(Some("/tmp/builder_build_full/option"))
169+
.mandatory("/tmp/builder_build_full/mandatory")
170+
.build();
171+
assert_eq!(
172+
Named {
173+
mandatory: PathBuf::from("/tmp/builder_build_full/mandatory"),
174+
option: Some(PathBuf::from("/tmp/builder_build_full/option")),
175+
},
176+
built,
177+
);
178+
}
179+
156180
#[test]
157181
fn named_builder_build_partial_implicit() {
158182
let built = Named::builder()
@@ -181,6 +205,7 @@ fn named_builder_build_partial_explicit() {
181205
built,
182206
);
183207
}
208+
184209
#[test]
185210
fn named_builder_into_full() {
186211
let built = Named::builder()
@@ -196,6 +221,21 @@ fn named_builder_into_full() {
196221
);
197222
}
198223

224+
#[test]
225+
fn named_builder_into_full_optional() {
226+
let built = Named::builder()
227+
.mandatory("/tmp/builder_into_full/mandatory")
228+
.option_optional(Some("/tmp/builder_into_full/option"))
229+
.into();
230+
assert_eq!(
231+
Named {
232+
mandatory: PathBuf::from("/tmp/builder_into_full/mandatory"),
233+
option: Some(PathBuf::from("/tmp/builder_into_full/option")),
234+
},
235+
built,
236+
);
237+
}
238+
199239
#[test]
200240
fn named_builder_into_partial_implicit() {
201241
let built = Named::builder()
@@ -240,6 +280,21 @@ fn tuple_builder_build_full() {
240280
);
241281
}
242282

283+
#[test]
284+
fn tuple_builder_build_full_optional() {
285+
let built = Tuple::builder()
286+
.set1_optional(Some("/tmp/builder_build_full/option"))
287+
.set0("/tmp/builder_build_full/mandatory")
288+
.build();
289+
assert_eq!(
290+
Tuple(
291+
PathBuf::from("/tmp/builder_build_full/mandatory"),
292+
Some(PathBuf::from("/tmp/builder_build_full/option")),
293+
),
294+
built,
295+
);
296+
}
297+
243298
#[test]
244299
fn tuple_builder_build_partial_implicit() {
245300
let built = Tuple::builder()
@@ -284,6 +339,21 @@ fn tuple_builder_into_full() {
284339
);
285340
}
286341

342+
#[test]
343+
fn tuple_builder_into_full_optional() {
344+
let built = Tuple::builder()
345+
.set0("/tmp/builder_into_full/mandatory")
346+
.set1_optional(Some("/tmp/builder_into_full/option"))
347+
.into();
348+
assert_eq!(
349+
Tuple(
350+
PathBuf::from("/tmp/builder_into_full/mandatory"),
351+
Some(PathBuf::from("/tmp/builder_into_full/option")),
352+
),
353+
built,
354+
);
355+
}
356+
287357
#[test]
288358
fn tuple_builder_into_partial_implicit() {
289359
let built = Tuple::builder()
@@ -312,4 +382,3 @@ fn tuple_builder_into_partial_explicit() {
312382
built,
313383
);
314384
}
315-

0 commit comments

Comments
 (0)