use type_state_builder::TypeStateBuilder;
#[derive(TypeStateBuilder, Debug, PartialEq)]
#[builder(setter_prefix = "with_")]
struct PersonWithPrefix {
#[builder(required)]
name: String,
#[builder(required)]
age: u32,
email: Option<String>,
phone: Option<String>,
}
#[derive(TypeStateBuilder, Debug, PartialEq)]
#[builder(setter_prefix = "with_")]
struct MixedPrefixes {
#[builder(required)]
name: String,
#[builder(required, setter_prefix = "set_")]
age: u32,
#[builder(setter_prefix = "use_")]
email: Option<String>,
phone: Option<String>,
}
#[derive(TypeStateBuilder, Debug, PartialEq)]
struct CustomNamesWithPrefixes {
#[builder(required, setter_name = "full_name", setter_prefix = "with_")]
name: String,
#[builder(required)]
age: u32,
#[builder(setter_name = "contact", setter_prefix = "set_")]
email: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_struct_level_setter_prefix() {
let person = PersonWithPrefix::builder()
.with_name("Alice".to_string())
.with_age(30)
.with_email(Some("alice@example.com".to_string()))
.with_phone(Some("123-456-7890".to_string()))
.build();
assert_eq!(person.name, "Alice");
assert_eq!(person.age, 30);
assert_eq!(person.email, Some("alice@example.com".to_string()));
assert_eq!(person.phone, Some("123-456-7890".to_string()));
}
#[test]
fn test_struct_level_prefix_with_defaults() {
let person = PersonWithPrefix::builder()
.with_name("Bob".to_string())
.with_age(25)
.build();
assert_eq!(person.name, "Bob");
assert_eq!(person.age, 25);
assert_eq!(person.email, None);
assert_eq!(person.phone, None);
}
#[test]
fn test_field_level_prefix_overrides_struct_level() {
let mixed = MixedPrefixes::builder()
.with_name("Charlie".to_string()) .set_age(35) .use_email(Some("charlie@example.com".to_string())) .with_phone(Some("987-654-3210".to_string())) .build();
assert_eq!(mixed.name, "Charlie");
assert_eq!(mixed.age, 35);
assert_eq!(mixed.email, Some("charlie@example.com".to_string()));
assert_eq!(mixed.phone, Some("987-654-3210".to_string()));
}
#[test]
fn test_field_level_prefix_without_struct_level() {
let custom = CustomNamesWithPrefixes::builder()
.with_full_name("Diana".to_string()) .age(28) .set_contact(Some("diana@example.com".to_string())) .build();
assert_eq!(custom.name, "Diana");
assert_eq!(custom.age, 28);
assert_eq!(custom.email, Some("diana@example.com".to_string()));
}
#[test]
fn test_method_chaining_with_prefixes() {
let person = PersonWithPrefix::builder()
.with_name("Eve".to_string())
.with_age(32)
.with_email(Some("eve@example.com".to_string()))
.build();
assert_eq!(person.name, "Eve");
assert_eq!(person.age, 32);
assert_eq!(person.email, Some("eve@example.com".to_string()));
assert_eq!(person.phone, None);
}
#[test]
fn test_required_fields_with_prefixes() {
let person = PersonWithPrefix::builder()
.with_name("Frank".to_string())
.with_age(40)
.build();
assert_eq!(person.name, "Frank");
assert_eq!(person.age, 40);
}
#[test]
fn test_mixed_prefix_scenarios() {
let mixed = MixedPrefixes::builder()
.with_name("Grace".to_string()) .set_age(45) .use_email(Some("grace@example.com".to_string())) .build();
assert_eq!(mixed.name, "Grace");
assert_eq!(mixed.age, 45);
assert_eq!(mixed.email, Some("grace@example.com".to_string()));
assert_eq!(mixed.phone, None); }
#[test]
fn test_type_safety_with_prefixes() {
let _valid = PersonWithPrefix::builder()
.with_name("Henry".to_string())
.with_age(50)
.build();
}
#[test]
fn test_prefix_with_different_types() {
let custom = CustomNamesWithPrefixes::builder()
.with_full_name("Iris".to_string()) .age(22) .set_contact(Some("iris@example.com".to_string())) .build();
assert_eq!(custom.name, "Iris");
assert_eq!(custom.age, 22);
assert_eq!(custom.email, Some("iris@example.com".to_string()));
}
}