diff --git a/CHANGELOG.md b/CHANGELOG.md
index f5e2bfe..50a9eac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ Source: https://keepachangelog.com/
### Added
- Add nested `fields(...)` value for struct attribute `#[builder]` (#32)
+- Add `fields(Default=!)` for struct attribute `#[builder]` (#32)
## [1.1.0] - 2024-08-26
diff --git a/CRATES_IO.md b/CRATES_IO.md
index 6ef48ab..26a51b7 100644
--- a/CRATES_IO.md
+++ b/CRATES_IO.md
@@ -51,6 +51,9 @@ Enforce [`Default`][Default] support for **struct**. See ["`Default` struct"](#d
* **`fields(Option=!)`**
Disable automatic [`Option`][Option] detection for **fields**. See ["`Option` fields"](#option-fields).
+* **`fields(Default=!)`**
+Disable automatic [`Default`][Default] detection for **fields**. See ["`Default` fields"](#default-fields).
+
* **`fields(Into=!)`**
Disable [`Into`][Into] for **fields**. See ["`Into` argument"](#into-argument).
diff --git a/macon_derive/src/attributes.rs b/macon_derive/src/attributes.rs
index 9421214..96ab02c 100644
--- a/macon_derive/src/attributes.rs
+++ b/macon_derive/src/attributes.rs
@@ -27,6 +27,7 @@ pub struct StructBuilder {
#[derive(Debug, Default, PartialEq)]
pub struct StructBuilderFields {
option: Setting<()>,
+ default: Setting<()>,
into: Setting<()>,
}
@@ -119,6 +120,13 @@ impl StructBuilderFields {
&mut self.option
}
+ pub fn default(&self) -> &Setting<()> {
+ &self.default
+ }
+ pub fn default_mut(&mut self) -> &mut Setting<()> {
+ &mut self.default
+ }
+
pub fn into_(&self) -> &Setting<()> {
&self.into
}
@@ -131,6 +139,9 @@ impl StructBuilderFields {
if nested.path.is_ident("Option") {
self.option = Setting::<()>::from_parse_nested_meta(nested)
.map_err_context("Unable to parse Option for fields struct builder attribute")?;
+ } else if nested.path.is_ident("Default") {
+ self.default = Setting::<()>::from_parse_nested_meta(nested)
+ .map_err_context("Unable to parse Default for fields struct builder attribute")?;
} else if nested.path.is_ident("Into") {
self.into = Setting::<()>::from_parse_nested_meta(nested)
.map_err_context("Unable to parse Into for fields struct builder attribute")?;
@@ -293,6 +304,11 @@ pub mod tests {
Setting::undefined(),
"fields.into",
);
+ assert_eq!(
+ builder.fields.default,
+ Setting::undefined(),
+ "fields.default",
+ );
assert_eq!(
builder.fields.option,
Setting::undefined(),
@@ -323,6 +339,11 @@ pub mod tests {
Setting::undefined(),
"fields.into",
);
+ assert_eq!(
+ builder.fields.default,
+ Setting::undefined(),
+ "fields.default",
+ );
assert_eq!(
builder.fields.option,
Setting::undefined(),
@@ -353,6 +374,11 @@ pub mod tests {
Setting::undefined(),
"fields.into",
);
+ assert_eq!(
+ builder.fields.default,
+ Setting::undefined(),
+ "fields.default",
+ );
assert_eq!(
builder.fields.option,
Setting::undefined(),
@@ -384,6 +410,11 @@ pub mod tests {
Setting::undefined(),
"fields.into",
);
+ assert_eq!(
+ builder.fields.default,
+ Setting::undefined(),
+ "fields.default",
+ );
assert_eq!(
builder.fields.option,
Setting::undefined(),
@@ -414,6 +445,11 @@ pub mod tests {
Setting::enable((), span()),
"fields.into",
);
+ assert_eq!(
+ builder.fields.default,
+ Setting::undefined(),
+ "fields.default",
+ );
assert_eq!(
builder.fields.option,
Setting::undefined(),
@@ -444,6 +480,11 @@ pub mod tests {
Setting::disable(span()),
"fields.into",
);
+ assert_eq!(
+ builder.fields.default,
+ Setting::undefined(),
+ "fields.default",
+ );
assert_eq!(
builder.fields.option,
Setting::undefined(),
@@ -474,6 +515,11 @@ pub mod tests {
Setting::undefined(),
"fields.into",
);
+ assert_eq!(
+ builder.fields.default,
+ Setting::undefined(),
+ "fields.default",
+ );
assert_eq!(
builder.fields.option,
Setting::enable((), span()),
@@ -504,6 +550,11 @@ pub mod tests {
Setting::undefined(),
"fields.into",
);
+ assert_eq!(
+ builder.fields.default,
+ Setting::undefined(),
+ "fields.default",
+ );
assert_eq!(
builder.fields.option,
Setting::disable(span()),
@@ -534,6 +585,11 @@ pub mod tests {
Setting::enable((), span()),
"fields.into",
);
+ assert_eq!(
+ builder.fields.default,
+ Setting::undefined(),
+ "fields.default",
+ );
assert_eq!(
builder.fields.option,
Setting::undefined(),
@@ -564,6 +620,81 @@ pub mod tests {
Setting::disable(span()),
"fields.into",
);
+ assert_eq!(
+ builder.fields.default,
+ Setting::undefined(),
+ "fields.default",
+ );
+ assert_eq!(
+ builder.fields.option,
+ Setting::undefined(),
+ "fields.option",
+ );
+ }
+
+ #[test]
+ fn struct_builder_attribute_fields_default_enabled() {
+ let derive_input: DeriveInput = parse_quote! {
+ #[builder(fields(Default))]
+ struct Foobar;
+ };
+ let builder = StructBuilder::from_input(&derive_input)
+ .expect("StructBuilder::from_input");
+ assert_eq!(
+ builder.mode,
+ Setting::undefined(),
+ "mode",
+ );
+ assert_eq!(
+ builder.default,
+ Setting::undefined(),
+ "default",
+ );
+ assert_eq!(
+ builder.fields.into,
+ Setting::undefined(),
+ "fields.into",
+ );
+ assert_eq!(
+ builder.fields.default,
+ Setting::enable((), span()),
+ "fields.default",
+ );
+ assert_eq!(
+ builder.fields.option,
+ Setting::undefined(),
+ "fields.option",
+ );
+ }
+
+ #[test]
+ fn struct_builder_attribute_fields_default_disabled() {
+ let derive_input: DeriveInput = parse_quote! {
+ #[builder(fields(Default=!))]
+ struct Foobar;
+ };
+ let builder = StructBuilder::from_input(&derive_input)
+ .expect("StructBuilder::from_input");
+ assert_eq!(
+ builder.mode,
+ Setting::undefined(),
+ "mode",
+ );
+ assert_eq!(
+ builder.default,
+ Setting::undefined(),
+ "default",
+ );
+ assert_eq!(
+ builder.fields.into,
+ Setting::undefined(),
+ "fields.into",
+ );
+ assert_eq!(
+ builder.fields.default,
+ Setting::disable(span()),
+ "fields.default",
+ );
assert_eq!(
builder.fields.option,
Setting::undefined(),
@@ -594,6 +725,11 @@ pub mod tests {
Setting::undefined(),
"fields.into",
);
+ assert_eq!(
+ builder.fields.default,
+ Setting::undefined(),
+ "fields.default",
+ );
assert_eq!(
builder.fields.option,
Setting::enable((), span()),
@@ -624,6 +760,11 @@ pub mod tests {
Setting::undefined(),
"fields.into",
);
+ assert_eq!(
+ builder.fields.default,
+ Setting::undefined(),
+ "fields.default",
+ );
assert_eq!(
builder.fields.option,
Setting::disable(span()),
diff --git a/macon_derive/src/model.rs b/macon_derive/src/model.rs
index d5110e2..1dbe11d 100644
--- a/macon_derive/src/model.rs
+++ b/macon_derive/src/model.rs
@@ -77,10 +77,10 @@ pub struct PropertySettings {
pub struct Properties {
/// Is Tuple struct `(a,b,c)` or Named one `{ a:A, b:B, c:C }`
pub is_tuple: bool,
- /// Is Default supported for struct
- pub default: Setting<()>,
/// Is Into supported for fields
pub into: Setting<()>,
+ /// Is Default supported for fields
+ pub default: Setting<()>,
/// Is Option supported for fields
pub option: Setting<()>,
/// Struct fields
@@ -183,8 +183,9 @@ impl Builder {
self.mode = builder.mode().try_into()?;
self.set_default(builder.default().clone());
- self.properties.option = builder.fields().option().clone();
- self.properties.into = builder.fields().into_().clone();
+ self.properties.option = builder.fields().option().clone();
+ self.properties.default = builder.fields().default().clone();
+ self.properties.into = builder.fields().into_().clone();
if ! self.default.is_defined() {
if let Some(span) = derives.get_type("Default") {
@@ -235,7 +236,6 @@ impl Builder {
pub fn set_default(&mut self, default: Setting<()>) {
self.default = default;
- self.properties.default = default;
}
}
@@ -258,11 +258,15 @@ impl Property {
builder_attribute.option().clone()
};
let default = if builder_attribute.default().is_undefined() {
- let default_types = crate::config::get().default_types();
- if default_types.match_type(&field.ty) {
- Setting::enable((), span)
- } else {
+ if builder.properties.default.is_disabled() {
Setting::disable(span)
+ } else {
+ let default_types = crate::config::get().default_types();
+ if default_types.match_type(&field.ty) {
+ Setting::enable((), span)
+ } else {
+ Setting::disable(span)
+ }
}
} else {
builder_attribute.default().clone()
@@ -700,6 +704,10 @@ pub mod tests {
use super::*;
+ fn span() -> Span {
+ Span::call_site()
+ }
+
fn newbuilder(derive: DeriveInput) -> Builder {
Builder::from_input(derive).expect("Builder::from_input")
}
@@ -754,7 +762,7 @@ pub mod tests {
});
assert_eq!(
builder.properties.into,
- Setting::disable(Span::call_site()),
+ Setting::disable(span()),
);
}
@@ -857,7 +865,7 @@ pub mod tests {
struct Demo;
});
- assert_eq!(builder.default, Setting::enable((), Span::call_site()), "builder.default");
+ assert_eq!(builder.default, Setting::enable((), span()), "builder.default");
}
#[test]
@@ -868,7 +876,7 @@ pub mod tests {
struct Demo;
});
- assert_eq!(builder.default, Setting::enable((), Span::call_site()), "builder.default")
+ assert_eq!(builder.default, Setting::enable((), span()), "builder.default")
}
#[test]
@@ -879,6 +887,62 @@ pub mod tests {
struct Demo;
});
- assert_eq!(builder.default, Setting::disable(Span::call_site()), "builder.default")
+ assert_eq!(builder.default, Setting::disable(span()), "builder.default")
+ }
+
+ #[test]
+ fn builder_derive_fields_default_disabled() {
+ let builder = newbuilder(parse_quote! {
+ #[builder(fields(Default=!))]
+ struct Foobar {
+ foobar: usize,
+ }
+ });
+
+ assert_eq!(builder.properties.default, Setting::disable(span()), "builder.properties.default");
+
+ let mut properties = builder.properties.items.iter();
+ let mut property_opt = properties.next();
+ assert!(property_opt.is_some(), "builder.properties.items[0]");
+ let property = property_opt.unwrap();
+ assert_eq!(property.default, Setting::disable(span()), "builder.properties.items[0].default");
+
+ property_opt = properties.next();
+ assert!(property_opt.is_none(), "builder.properties.items[1]");
+ }
+
+ #[test]
+ fn builder_derive_fields_default_disabled_with_customized_fields() {
+ let builder = newbuilder(parse_quote! {
+ #[builder(fields(Default=!))]
+ struct Foobar {
+ foo: usize,
+ #[builder(Default)]
+ bar: usize,
+ baz: usize,
+ }
+ });
+
+ assert_eq!(builder.properties.default, Setting::disable(span()), "builder.properties.default");
+
+ let mut properties = builder.properties.items.iter();
+
+ let mut property_opt = properties.next();
+ assert!(property_opt.is_some(), "builder.properties.items[0]");
+ let mut property = property_opt.unwrap();
+ assert_eq!(property.default, Setting::disable(span()), "builder.properties.items[0].default");
+
+ property_opt = properties.next();
+ assert!(property_opt.is_some(), "builder.properties.items[1]");
+ property = property_opt.unwrap();
+ assert_eq!(property.default, Setting::enable((), span()), "builder.properties.items[1].default");
+
+ property_opt = properties.next();
+ assert!(property_opt.is_some(), "builder.properties.items[2]");
+ property = property_opt.unwrap();
+ assert_eq!(property.default, Setting::disable(span()), "builder.properties.items[2].default");
+
+ property_opt = properties.next();
+ assert!(property_opt.is_none(), "builder.properties.items[3]");
}
}
diff --git a/src/lib.rs b/src/lib.rs
index cc51b9a..29ca457 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -51,6 +51,9 @@
//! * **`fields(Option=!)`**
//! Disable automatic [`Option`] detection for **fields**. See ["`Option` fields"](#option-fields).
//!
+//! * **`fields(Default=!)`**
+//! Disable automatic [`Default`] detection for **fields**. See ["`Default` fields"](#default-fields).
+//!
//! * **`fields(Into=!)`**
//! Disable [`Into`] for **fields**. See ["`Into` argument"](#into-argument).
//!
diff --git a/tests/macro_panic_default_field_all_disabled.rs b/tests/macro_panic_default_field_all_disabled.rs
new file mode 100644
index 0000000..792d2af
--- /dev/null
+++ b/tests/macro_panic_default_field_all_disabled.rs
@@ -0,0 +1,134 @@
+use macon::Builder;
+
+// #############################################################################
+// ################################### INPUT ###################################
+// #############################################################################
+use ::std::path::PathBuf;
+
+#[derive(Builder)]
+#[builder(mode=Panic,fields(Default=!),)]
+#[derive(PartialEq,Debug,)]
+struct StructNamed {
+ id: i32,
+ value: String,
+ optional: Option,
+ #[builder(Default)]
+ exception: String,
+ mandatory: PathBuf,
+}
+
+#[derive(Builder)]
+#[builder(mode=Panic,fields(Default=!),)]
+#[derive(PartialEq,Debug,)]
+struct StructTuple(
+ i32,
+ String,
+ Option,
+ #[builder(Default)]
+ String,
+ PathBuf,
+);
+
+// #############################################################################
+// ################################### TESTS ###################################
+// #############################################################################
+
+#[test]
+#[should_panic(expected="Field id is missing\nField value is missing")]
+fn named_build_default_implicit() {
+ StructNamed::builder()
+ .mandatory("/dev/null")
+ .build();
+}
+
+#[test]
+fn named_build_default_explicit_none() {
+ let built = StructNamed::builder()
+ .id(43)
+ .value("another value")
+ .optional_none()
+ .exception_default()
+ .mandatory("/dev/null")
+ .build();
+ assert_eq!(
+ StructNamed {
+ id: 43,
+ value: String::from("another value"),
+ optional: None,
+ exception: String::from(""),
+ mandatory: PathBuf::from("/dev/null"),
+ },
+ built,
+ )
+}
+
+#[test]
+fn named_build_full() {
+ let built = StructNamed::builder()
+ .id(44)
+ .value("any value")
+ .optional("optional")
+ .exception("exception")
+ .mandatory("/dev/null")
+ .build();
+ assert_eq!(
+ StructNamed {
+ id: 44,
+ value: String::from("any value"),
+ optional: Some(String::from("optional")),
+ exception: String::from("exception"),
+ mandatory: PathBuf::from("/dev/null"),
+ },
+ built,
+ )
+}
+
+#[test]
+#[should_panic(expected="Field 0 is missing\nField 1 is missing")]
+fn tuple_build_default_implicit() {
+ StructTuple::builder()
+ .set3("/dev/null")
+ .build();
+}
+
+#[test]
+fn tuple_build_unordered_default_explicit_none() {
+ let built = StructTuple::builder()
+ .set0(43)
+ .set1("another value")
+ .set2_none()
+ .set3_default()
+ .set4("/dev/null")
+ .build();
+ assert_eq!(
+ StructTuple(
+ 43,
+ String::from("another value"),
+ None,
+ String::from(""),
+ PathBuf::from("/dev/null"),
+ ),
+ built,
+ )
+}
+
+#[test]
+fn tuple_build_unordered_full() {
+ let built = StructTuple::builder()
+ .set0(44)
+ .set1("any value")
+ .set2("optional")
+ .set3("exception")
+ .set4("/dev/null")
+ .build();
+ assert_eq!(
+ StructTuple(
+ 44,
+ String::from("any value"),
+ Some(String::from("optional")),
+ String::from("exception"),
+ PathBuf::from("/dev/null"),
+ ),
+ built,
+ )
+}
diff --git a/tests/macro_result_default_field_all_disabled.rs b/tests/macro_result_default_field_all_disabled.rs
new file mode 100644
index 0000000..5c7f19b
--- /dev/null
+++ b/tests/macro_result_default_field_all_disabled.rs
@@ -0,0 +1,141 @@
+use macon::Builder;
+
+// #############################################################################
+// ################################### INPUT ###################################
+// #############################################################################
+use ::std::path::PathBuf;
+
+#[derive(Builder)]
+#[builder(mode=Result,fields(Default=!),)]
+#[derive(PartialEq,Debug,)]
+struct StructNamed {
+ id: i32,
+ value: String,
+ optional: Option,
+ #[builder(Default)]
+ exception: String,
+ mandatory: PathBuf,
+}
+
+#[derive(Builder)]
+#[builder(mode=Result,fields(Default=!),)]
+#[derive(PartialEq,Debug,)]
+struct StructTuple(
+ i32,
+ String,
+ Option,
+ #[builder(Default)]
+ String,
+ PathBuf,
+);
+
+
+// #############################################################################
+// ################################### TESTS ###################################
+// #############################################################################
+
+#[test]
+fn named_build_default_implicit() {
+ let built = StructNamed::builder()
+ .mandatory("/dev/null")
+ .build();
+ assert_eq!(
+ Err(String::from("Field id is missing\nField value is missing")),
+ built,
+ )
+}
+
+#[test]
+fn named_build_default_explicit_none() {
+ let built = StructNamed::builder()
+ .id(43)
+ .value("another value")
+ .optional_none()
+ .exception_default()
+ .mandatory("/dev/null")
+ .build();
+ assert_eq!(
+ Ok(StructNamed {
+ id: 43,
+ value: String::from("another value"),
+ optional: None,
+ exception: String::from(""),
+ mandatory: PathBuf::from("/dev/null"),
+ }),
+ built,
+ )
+}
+
+#[test]
+fn named_build_full() {
+ let built = StructNamed::builder()
+ .id(44)
+ .value("any value")
+ .optional("optional")
+ .exception("exception")
+ .mandatory("/dev/null")
+ .build();
+ assert_eq!(
+ Ok(StructNamed {
+ id: 44,
+ value: String::from("any value"),
+ optional: Some(String::from("optional")),
+ exception: String::from("exception"),
+ mandatory: PathBuf::from("/dev/null"),
+ }),
+ built,
+ )
+}
+
+#[test]
+fn tuple_build_default_implicit() {
+ let built = StructTuple::builder()
+ .set4("/dev/null")
+ .build();
+ assert_eq!(
+ Err(String::from("Field 0 is missing\nField 1 is missing")),
+ built,
+ )
+}
+
+#[test]
+fn tuple_build_unordered_default_explicit_none() {
+ let built = StructTuple::builder()
+ .set0(43)
+ .set1("another value")
+ .set2_none()
+ .set3_default()
+ .set4("/dev/null")
+ .build();
+ assert_eq!(
+ Ok(StructTuple(
+ 43,
+ String::from("another value"),
+ None,
+ String::from(""),
+ PathBuf::from("/dev/null"),
+ )),
+ built,
+ )
+}
+
+#[test]
+fn tuple_build_unordered_full() {
+ let built = StructTuple::builder()
+ .set0(44)
+ .set1("any value")
+ .set2("optional")
+ .set3("exception")
+ .set4("/dev/null")
+ .build();
+ assert_eq!(
+ Ok(StructTuple(
+ 44,
+ String::from("any value"),
+ Some(String::from("optional")),
+ String::from("exception"),
+ PathBuf::from("/dev/null"),
+ )),
+ built,
+ )
+}
diff --git a/tests/macro_typestate_default_field_all_disabled.rs b/tests/macro_typestate_default_field_all_disabled.rs
new file mode 100644
index 0000000..a2a6a09
--- /dev/null
+++ b/tests/macro_typestate_default_field_all_disabled.rs
@@ -0,0 +1,198 @@
+use macon::Builder;
+
+// #############################################################################
+// ################################### INPUT ###################################
+// #############################################################################
+use ::std::path::PathBuf;
+
+#[derive(Builder)]
+#[builder(mode=Typestate,fields(Default=!),)]
+#[derive(PartialEq,Debug,)]
+struct StructNamed {
+ id: i32,
+ value: String,
+ optional: Option,
+ #[builder(Default)]
+ exception: String,
+ mandatory: PathBuf,
+}
+
+#[derive(Builder)]
+#[builder(mode=Typestate,fields(Default=!),)]
+#[derive(PartialEq,Debug,)]
+struct StructTuple(
+ i32,
+ String,
+ Option,
+ #[builder(Default)]
+ String,
+ PathBuf,
+);
+
+// #############################################################################
+// ################################### TESTS ###################################
+// #############################################################################
+
+#[test]
+fn named_build_minimum() {
+ let built = StructNamed::builder()
+ .id(42)
+ .value("a value")
+ .mandatory("/dev/null")
+ .build();
+ assert_eq!(
+ StructNamed {
+ id: 42,
+ value: String::from("a value"),
+ optional: None,
+ exception: String::from(""),
+ mandatory: PathBuf::from("/dev/null"),
+ },
+ built,
+ )
+}
+
+#[test]
+fn named_build_default_explicit_none() {
+ let built = StructNamed::builder()
+ .id(43)
+ .value("another value")
+ .optional_none()
+ .exception_default()
+ .mandatory("/dev/null")
+ .build();
+ assert_eq!(
+ StructNamed {
+ id: 43,
+ value: String::from("another value"),
+ optional: None,
+ exception: String::from(""),
+ mandatory: PathBuf::from("/dev/null"),
+ },
+ built,
+ )
+}
+
+#[test]
+fn named_build_full() {
+ let built = StructNamed::builder()
+ .id(44)
+ .value("any value")
+ .optional("optional")
+ .exception("exception")
+ .mandatory("/dev/null")
+ .build();
+ assert_eq!(
+ StructNamed {
+ id: 44,
+ value: String::from("any value"),
+ optional: Some(String::from("optional")),
+ exception: String::from("exception"),
+ mandatory: PathBuf::from("/dev/null"),
+ },
+ built,
+ )
+}
+
+#[test]
+fn tuple_build_minimum() {
+ let built = StructTuple::builder()
+ .set0(42)
+ .set1("a value")
+ .set4("/dev/null")
+ .build();
+ assert_eq!(
+ StructTuple(
+ 42,
+ String::from("a value"),
+ None,
+ String::from(""),
+ PathBuf::from("/dev/null"),
+ ),
+ built,
+ )
+}
+
+#[test]
+fn tuple_build_unordered_default_explicit_none() {
+ let built = StructTuple::builder()
+ .set0(43)
+ .set1("another value")
+ .set2_none()
+ .set3_default()
+ .set4("/dev/null")
+ .build();
+ assert_eq!(
+ StructTuple(
+ 43,
+ String::from("another value"),
+ None,
+ String::from(""),
+ PathBuf::from("/dev/null"),
+ ),
+ built,
+ )
+}
+
+#[test]
+fn tuple_build_unordered_full() {
+ let built = StructTuple::builder()
+ .set0(44)
+ .set1("any value")
+ .set2("optional")
+ .set3("exception")
+ .set4("/dev/null")
+ .build();
+ assert_eq!(
+ StructTuple(
+ 44,
+ String::from("any value"),
+ Some(String::from("optional")),
+ String::from("exception"),
+ PathBuf::from("/dev/null"),
+ ),
+ built,
+ )
+}
+
+#[test]
+fn tuple_build_ordered_default_explicit_none() {
+ let built = StructTuple::builder()
+ .set(43)
+ .set("another value")
+ .none()
+ .default()
+ .set("/dev/null")
+ .build();
+ assert_eq!(
+ StructTuple(
+ 43,
+ String::from("another value"),
+ None,
+ String::from(""),
+ PathBuf::from("/dev/null"),
+ ),
+ built,
+ )
+}
+
+#[test]
+fn tuple_ordered_build_full() {
+ let built = StructTuple::builder()
+ .set(44)
+ .set("any value")
+ .set("optional")
+ .set("exception")
+ .set("/dev/null")
+ .build();
+ assert_eq!(
+ StructTuple(
+ 44,
+ String::from("any value"),
+ Some(String::from("optional")),
+ String::from("exception"),
+ PathBuf::from("/dev/null"),
+ ),
+ built,
+ )
+}