Skip to content

Commit

Permalink
Add MappedLocalTime::and_then
Browse files Browse the repository at this point in the history
  • Loading branch information
pitdicker committed Mar 22, 2024
1 parent 3adfd88 commit e05ba8b
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/offset/local/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,6 @@ impl Cache {
self.zone
.find_local_time_type_from_local(d.and_utc().timestamp(), d.year())
.expect("unable to select local time type")
.map(|o| FixedOffset::east_opt(o.offset()).unwrap())
.and_then(|o| FixedOffset::east_opt(o.offset()))
}
}
43 changes: 23 additions & 20 deletions src/offset/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,24 @@ impl<T> MappedLocalTime<T> {
MappedLocalTime::Ambiguous(min, max) => MappedLocalTime::Ambiguous(f(min), f(max)),
}
}

/// Maps a `MappedLocalTime<T>` into `MappedLocalTime<U>` with given function.
///
/// Returns `MappedLocalTime::None` if the function returns `None`.
#[must_use]
pub(crate) fn and_then<U, F: FnMut(T) -> Option<U>>(self, mut f: F) -> MappedLocalTime<U> {
match self {
MappedLocalTime::None => MappedLocalTime::None,
MappedLocalTime::Single(v) => match f(v) {
Some(new) => MappedLocalTime::Single(new),
None => MappedLocalTime::None,
},
MappedLocalTime::Ambiguous(min, max) => match (f(min), f(max)) {
(Some(min), Some(max)) => MappedLocalTime::Ambiguous(min, max),
_ => MappedLocalTime::None,
},
}
}
}

/// The conversion result from the local time to the timezone-aware datetime types.
Expand Down Expand Up @@ -547,26 +565,11 @@ pub trait TimeZone: Sized + Clone {
/// Converts the local `NaiveDateTime` to the timezone-aware `DateTime` if possible.
#[allow(clippy::wrong_self_convention)]
fn from_local_datetime(&self, local: &NaiveDateTime) -> MappedLocalTime<DateTime<Self>> {
// Return `MappedLocalTime::None` when the offset pushes a value out of range, instead of
// panicking.
match self.offset_from_local_datetime(local) {
MappedLocalTime::None => MappedLocalTime::None,
MappedLocalTime::Single(offset) => match local.checked_sub_offset(offset.fix()) {
Some(dt) => {
MappedLocalTime::Single(DateTime::from_naive_utc_and_offset(dt, offset))
}
None => MappedLocalTime::None,
},
MappedLocalTime::Ambiguous(o1, o2) => {
match (local.checked_sub_offset(o1.fix()), local.checked_sub_offset(o2.fix())) {
(Some(d1), Some(d2)) => MappedLocalTime::Ambiguous(
DateTime::from_naive_utc_and_offset(d1, o1),
DateTime::from_naive_utc_and_offset(d2, o2),
),
_ => MappedLocalTime::None,
}
}
}
self.offset_from_local_datetime(local).and_then(|off| {
local
.checked_sub_offset(off.fix())
.map(|dt| DateTime::from_naive_utc_and_offset(dt, off))
})
}

/// Creates the offset for given UTC `NaiveDate`. This cannot fail.
Expand Down

0 comments on commit e05ba8b

Please sign in to comment.