calendar.rs (2040B)
1 //! Output values retain civil components separately from exact wire instants. 2 use radroots_event::calendar::CalendarDate; 3 use tera_core::runtime::product_surface::CalendarTiming; 4 5 pub const TODAY_CARD_FFI_SCHEMA_VERSION: u16 = 2; 6 7 #[derive(Clone, Debug, Eq, PartialEq, uniffi::Record)] 8 pub struct FfiCivilDate { 9 pub year: u16, 10 pub month: u8, 11 pub day: u8, 12 } 13 14 impl From<&CalendarDate> for FfiCivilDate { 15 fn from(value: &CalendarDate) -> Self { 16 // The shared private representation guarantees ten canonical ASCII 17 // bytes and a valid Gregorian date. This is component translation only. 18 let bytes = value.as_str().as_bytes(); 19 let digit = |index: usize| u16::from(bytes[index] - b'0'); 20 Self { 21 year: digit(0) * 1_000 + digit(1) * 100 + digit(2) * 10 + digit(3), 22 month: (digit(5) * 10 + digit(6)) as u8, 23 day: (digit(8) * 10 + digit(9)) as u8, 24 } 25 } 26 } 27 28 #[derive(Clone, Debug, Eq, PartialEq, uniffi::Enum)] 29 pub enum FfiCalendarTiming { 30 DateBased { 31 start: FfiCivilDate, 32 end_exclusive: Option<FfiCivilDate>, 33 }, 34 TimeBased { 35 start_unix_s: u64, 36 end_exclusive_unix_s: Option<u64>, 37 start_tzid: Option<String>, 38 end_tzid: Option<String>, 39 }, 40 } 41 42 impl From<CalendarTiming> for FfiCalendarTiming { 43 fn from(value: CalendarTiming) -> Self { 44 match value { 45 CalendarTiming::DateBased(timing) => Self::DateBased { 46 start: timing.start().into(), 47 end_exclusive: timing.end_exclusive().map(Into::into), 48 }, 49 CalendarTiming::TimeBased(timing) => Self::TimeBased { 50 start_unix_s: timing.start(), 51 end_exclusive_unix_s: timing.end_exclusive(), 52 start_tzid: timing.start_tzid().map(|zone| zone.as_str().to_owned()), 53 end_tzid: timing.end_tzid().map(|zone| zone.as_str().to_owned()), 54 }, 55 } 56 } 57 } 58 59 #[cfg(test)] 60 #[path = "calendar_tests.rs"] 61 mod tests;