use comptime_builder::*; impl WithField<1, u16, Date> for DateBuilder { type Output = DateBuilder, M, D>; fn with_field(self, value: u16) -> Self::Output { DateBuilder { year: Field(value), month: self.month, day: self.day, } } } impl WithField<2, u8, Date> for DateBuilder { type Output = DateBuilder, D>; fn with_field(self, value: u8) -> Self::Output { DateBuilder { year: self.year, month: Field(value), day: self.day, } } } impl WithField<3, u8, Date> for DateBuilder { type Output = DateBuilder>; fn with_field(self, value: u8) -> Self::Output { DateBuilder { year: self.year, month: self.month, day: Field(value), } } } pub trait WithYear: WithField<1, u16, Date> { fn with_year(self, value: u16) -> Self::Output { self.with_field(value) } } impl WithYear for T where T: WithField<1, u16, Date> {} pub trait WithMonth: WithField<2, u8, Date> { fn with_month(self, value: u8) -> Self::Output { self.with_field(value) } } impl WithMonth for T where T: WithField<2, u8, Date> {} pub trait WithDay: WithField<3, u8, Date> { fn with_day(self, value: u8) -> Self::Output { self.with_field(value) } } impl WithDay for T where T: WithField<3, u8, Date> {} pub struct DateBuilder { year: Year, month: Month, day: Day, } impl DateBuilder, Field<2, u8>, Field<3, u8>> { fn build(self) -> Date { Date { year: self.year.0, month: self.month.0, day: self.day.0, } } } #[derive(Debug)] pub struct Date { year: u16, month: u8, day: u8, } pub struct Empty; impl Date { pub fn builder() -> DateBuilder { DateBuilder { year: Empty, month: Empty, day: Empty, } } } pub fn main() { let date = Date::builder() .with_year(2022) .with_month(5) .with_day(1) .build(); dbg!(date); }