use time::{Month, OffsetDateTime, PrimitiveDateTime, UtcOffset, Weekday}; use crate::error::{PartialVariant, TryFromPartial}; use crate::partial::{PartDate, PartPrimitiveDateTime, PartTime, Partial}; /// An [`PartOffsetDateTime`] struct represents a partial [`OffsetDateTime`] struct. #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] pub struct PartOffsetDateTime { datetime: PartPrimitiveDateTime, offset: Option, } impl PartOffsetDateTime { /// Creates a [`PartOffsetDateTime`] from its components. pub fn new(datetime: PartPrimitiveDateTime, offset: Option) -> Self { Self { datetime, offset } } } impl PartOffsetDateTime { /// Replaces the offset. pub fn offset(self) -> Option { self.offset } /// Returns the date. pub fn date(self) -> PartDate { self.datetime.date() } /// Returns the year. pub fn year(self) -> Option { self.datetime.year() } /// Returns the month. pub fn month(self) -> Option { self.datetime.month() } /// Returns the weekday. pub fn weekday(self) -> Option { self.datetime.weekday() } /// Returns the day of the month. pub fn day(self) -> Option { self.datetime.day() } /// Returns the time. pub fn time(self) -> PartTime { self.datetime.time() } /// Returns the clock hour. pub fn hour(self) -> Option { self.datetime.hour() } /// Returns the minute within the hour. pub fn minute(self) -> Option { self.datetime.minute() } /// Returns the second within the minute. pub fn second(self) -> Option { self.datetime.second() } /// Returns the milliseconds within the second. pub fn millisecond(self) -> Option { self.datetime.millisecond() } /// Returns the microseconds within the second. pub fn microsecond(self) -> Option { self.datetime.microsecond() } /// Returns the nanoseconds within the second. pub fn nanosecond(self) -> Option { self.datetime.nanosecond() } } impl PartOffsetDateTime { /// Replaces the offset. pub fn replace_offset(self, offset: Option) -> Result { Ok(Self::new(self.datetime, offset)) } /// Replaces the date and time. pub fn replace_date_time( self, datetime: PartPrimitiveDateTime, ) -> Result { Ok(Self::new(datetime, self.offset)) } /// Replaces the date. pub fn replace_date(self, date: PartDate) -> Result { self.replace_date_time(self.datetime.replace_date(date)?) } /// Replaces the year. pub fn replace_year(self, year: Option) -> Result { self.replace_date_time(self.datetime.replace_year(year)?) } /// Replace the month of the year. pub fn replace_month(self, month: Option) -> Result { self.replace_date_time(self.datetime.replace_month(month)?) } /// Replaces the day of the month. pub fn replace_day(self, day: Option) -> Result { self.replace_date_time(self.datetime.replace_day(day)?) } /// Returns the time. pub fn replace_time(self, time: PartTime) -> Result { self.replace_date_time(self.datetime.replace_time(time)?) } /// Returns the clock hour. pub fn replace_hour(self, hour: Option) -> Result { self.replace_date_time(self.datetime.replace_hour(hour)?) } /// Returns the minute within the hour. pub fn replace_minute(self, minute: Option) -> Result { self.replace_date_time(self.datetime.replace_minute(minute)?) } /// Returns the second within the minute. pub fn replace_second(self, second: Option) -> Result { self.replace_date_time(self.datetime.replace_second(second)?) } /// Returns the milliseconds within the second. pub fn replace_millisecond(self, millisecond: Option) -> Result { self.replace_date_time(self.datetime.replace_millisecond(millisecond)?) } /// Returns the microseconds within the second. pub fn replace_microsecond(self, microsecond: Option) -> Result { self.replace_date_time(self.datetime.replace_microsecond(microsecond)?) } /// Returns the nanoseconds within the second. pub fn replace_nanosecond(self, nanosecond: Option) -> Result { self.replace_date_time(self.datetime.replace_nanosecond(nanosecond)?) } } impl Partial for PartOffsetDateTime { type Complete = OffsetDateTime; fn from_complete(complete: Self::Complete) -> Self { let dt = PrimitiveDateTime::new(complete.date(), complete.time()); Self::new( PartPrimitiveDateTime::from_complete(dt), Some(complete.offset()), ) } fn into_complete(self) -> Result { let error: TryFromPartial = PartialVariant::new("offset").into(); let offset = self.offset.ok_or(error)?; Ok(self.datetime.into_complete()?.assume_offset(offset)) } fn with_fallback(self, fallback: Self::Complete) -> Result { let dt = PrimitiveDateTime::new(fallback.date(), fallback.time()); let dt = self.datetime.with_fallback(dt)?; let os = Some(self.offset.unwrap_or(fallback.offset())); Ok(Self::new(dt, os)) } } impl From for PartOffsetDateTime { fn from(datetime: OffsetDateTime) -> Self { Self::from_complete(datetime) } } impl TryFrom for OffsetDateTime { type Error = TryFromPartial; fn try_from(datetime: PartOffsetDateTime) -> Result { datetime.into_complete() } }