date_differencer/add_diff/
jiff_support.rs1use core::fmt;
2
3use jiff::{Zoned, civil::DateTime};
4
5use super::{AddDateTimeDiff, AddedDateTimeParts, DateTimeDiff, add_date_time_parts};
6
7#[inline]
8fn jiff_error(args: fmt::Arguments<'_>) -> jiff::Error {
9 jiff::Error::from_args(args)
10}
11
12#[inline]
13fn added_date_time_parts(
14 from: &impl super::DateTimeParts,
15 date_time_diff: &impl DateTimeDiff,
16) -> Result<AddedDateTimeParts, jiff::Error> {
17 add_date_time_parts(from, date_time_diff).ok_or_else(|| {
18 jiff_error(format_args!("date-time addition overflowed before constructing the Jiff value"))
19 })
20}
21
22#[inline]
23fn jiff_year(year: i32) -> Result<i16, jiff::Error> {
24 i16::try_from(year)
25 .map_err(|_| jiff_error(format_args!("date-time year is outside Jiff's supported range")))
26}
27
28impl AddDateTimeDiff for DateTime {
29 type Output = Result<DateTime, jiff::Error>;
30
31 #[inline]
32 fn add_date_time_diff(self, date_time_diff: &impl DateTimeDiff) -> Self::Output {
33 let parts = added_date_time_parts(&self, date_time_diff)?;
34
35 DateTime::new(
36 jiff_year(parts.year)?,
37 parts.month as i8,
38 parts.day as i8,
39 parts.hour as i8,
40 parts.minute as i8,
41 parts.second as i8,
42 parts.nanosecond as i32,
43 )
44 }
45}
46
47impl AddDateTimeDiff for Zoned {
48 type Output = Result<Zoned, jiff::Error>;
49
50 #[inline]
51 fn add_date_time_diff(self, date_time_diff: &impl DateTimeDiff) -> Self::Output {
52 let parts = added_date_time_parts(&self, date_time_diff)?;
53
54 self.with()
55 .year(jiff_year(parts.year)?)
56 .month(parts.month as i8)
57 .day(parts.day as i8)
58 .hour(parts.hour as i8)
59 .minute(parts.minute as i8)
60 .second(parts.second as i8)
61 .subsec_nanosecond(parts.nanosecond as i32)
62 .build()
63 }
64}