1use displaydoc::Display;
2use serde_derive::{Deserialize, Serialize};
3use tracing::debug;
4
5use crate::{
6 date::PaceDate,
7 date_time::PaceDateTime,
8 error::PaceTimeErrorKind,
9 flags::{DateFlags, TimeFlags},
10 time_range::TimeRangeOptions,
11 time_zone::PaceTimeZoneKind,
12};
13
14#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, Serialize, Deserialize, Display)]
15pub enum PaceTimeFrame {
16 CurrentMonth,
18
19 CurrentWeek,
21
22 CurrentYear,
24
25 DateRange(TimeRangeOptions),
27
28 SpecificDate(PaceDate),
30
31 LastMonth,
33
34 LastWeek,
36
37 LastYear,
39
40 #[default]
42 Today,
43
44 Yesterday,
46}
47
48impl
49 TryFrom<(
50 Option<&TimeFlags>,
51 Option<&DateFlags>,
52 PaceTimeZoneKind,
53 PaceTimeZoneKind,
54 )> for PaceTimeFrame
55{
56 type Error = PaceTimeErrorKind;
57
58 fn try_from(
59 (time_flags, date_flags, tz, tz_config): (
60 Option<&TimeFlags>,
61 Option<&DateFlags>,
62 PaceTimeZoneKind,
63 PaceTimeZoneKind,
64 ),
65 ) -> Result<Self, Self::Error> {
66 time_frame_from_date_and_time_flags_with_time_zone_kind(
67 time_flags, date_flags, tz, tz_config,
68 )
69 }
70}
71
72impl TryFrom<(Option<&TimeFlags>, Option<&DateFlags>, PaceTimeZoneKind)> for PaceTimeFrame {
73 type Error = PaceTimeErrorKind;
74
75 fn try_from(
76 (time_flags, date_flags, tz): (Option<&TimeFlags>, Option<&DateFlags>, PaceTimeZoneKind),
77 ) -> Result<Self, Self::Error> {
78 time_frame_from_date_and_time_flags_with_time_zone_kind(
79 time_flags,
80 date_flags,
81 tz,
82 PaceTimeZoneKind::NotSet,
83 )
84 }
85}
86
87impl TryFrom<(&DateFlags, PaceTimeZoneKind)> for PaceTimeFrame {
88 type Error = PaceTimeErrorKind;
89
90 fn try_from((date_flags, tz): (&DateFlags, PaceTimeZoneKind)) -> Result<Self, Self::Error> {
91 time_frame_from_date_and_time_flags_with_time_zone_kind(
92 None,
93 Some(date_flags),
94 tz,
95 PaceTimeZoneKind::NotSet,
96 )
97 }
98}
99
100impl TryFrom<&DateFlags> for PaceTimeFrame {
101 type Error = PaceTimeErrorKind;
102
103 fn try_from(date_flags: &DateFlags) -> Result<Self, Self::Error> {
104 time_frame_from_date_and_time_flags_with_time_zone_kind(
105 None,
106 Some(date_flags),
107 PaceTimeZoneKind::NotSet,
108 PaceTimeZoneKind::NotSet,
109 )
110 }
111}
112
113impl TryFrom<(Option<&DateFlags>, PaceTimeZoneKind)> for PaceTimeFrame {
114 type Error = PaceTimeErrorKind;
115
116 fn try_from(
117 (date_flags, tz): (Option<&DateFlags>, PaceTimeZoneKind),
118 ) -> Result<Self, Self::Error> {
119 time_frame_from_date_and_time_flags_with_time_zone_kind(
120 None,
121 date_flags,
122 tz,
123 PaceTimeZoneKind::NotSet,
124 )
125 }
126}
127
128impl TryFrom<(Option<&TimeFlags>, PaceTimeZoneKind)> for PaceTimeFrame {
129 type Error = PaceTimeErrorKind;
130
131 fn try_from(
132 (time_flags, tz): (Option<&TimeFlags>, PaceTimeZoneKind),
133 ) -> Result<Self, Self::Error> {
134 time_frame_from_date_and_time_flags_with_time_zone_kind(
135 time_flags,
136 None,
137 tz,
138 PaceTimeZoneKind::NotSet,
139 )
140 }
141}
142
143impl TryFrom<(&TimeFlags, PaceTimeZoneKind)> for PaceTimeFrame {
144 type Error = PaceTimeErrorKind;
145
146 fn try_from((time_flags, tz): (&TimeFlags, PaceTimeZoneKind)) -> Result<Self, Self::Error> {
147 time_frame_from_date_and_time_flags_with_time_zone_kind(
148 Some(time_flags),
149 None,
150 tz,
151 PaceTimeZoneKind::NotSet,
152 )
153 }
154}
155
156impl TryFrom<&TimeFlags> for PaceTimeFrame {
157 type Error = PaceTimeErrorKind;
158
159 fn try_from(time_flags: &TimeFlags) -> Result<Self, Self::Error> {
160 time_frame_from_date_and_time_flags_with_time_zone_kind(
161 Some(time_flags),
162 None,
163 PaceTimeZoneKind::NotSet,
164 PaceTimeZoneKind::NotSet,
165 )
166 }
167}
168
169impl TryFrom<PaceTimeZoneKind> for PaceTimeFrame {
170 type Error = PaceTimeErrorKind;
171
172 fn try_from(tz: PaceTimeZoneKind) -> Result<Self, Self::Error> {
173 time_frame_from_date_and_time_flags_with_time_zone_kind(
174 Some(&TimeFlags::default()),
175 None,
176 tz,
177 PaceTimeZoneKind::NotSet,
178 )
179 }
180}
181
182pub(crate) fn time_frame_from_date_and_time_flags_with_time_zone_kind(
199 time_flags: Option<&TimeFlags>,
200 date_flags: Option<&DateFlags>,
201 tz: PaceTimeZoneKind,
202 tz_config: PaceTimeZoneKind,
203) -> Result<PaceTimeFrame, PaceTimeErrorKind> {
204 let time_zone = match (tz, tz_config) {
205 (tzk, _) | (PaceTimeZoneKind::NotSet, tzk) if !tzk.is_not_set() => tzk,
206 _ => PaceTimeZoneKind::default(),
207 };
208
209 debug!("Using Time zone: {time_zone:?}");
210
211 let time_frame = match (time_flags, date_flags) {
212 (Some(TimeFlags::Today), _) => PaceTimeFrame::Today,
213 (Some(TimeFlags::Yesterday), _) => PaceTimeFrame::Yesterday,
214 (Some(TimeFlags::CurrentWeek), _) => PaceTimeFrame::CurrentWeek,
215 (Some(TimeFlags::LastWeek), _) => PaceTimeFrame::LastWeek,
216 (Some(TimeFlags::CurrentMonth), _) => PaceTimeFrame::CurrentMonth,
217 (Some(TimeFlags::LastMonth), _) => PaceTimeFrame::LastMonth,
218 (
219 None,
220 Some(DateFlags {
221 date: Some(specific_date),
222 from: None,
223 to: None,
224 }),
225 ) => {
226 PaceTimeFrame::SpecificDate(PaceDate::from(specific_date.to_owned()))
228 }
229 (
230 None,
231 Some(DateFlags {
232 date: None,
233 from: Some(from),
234 to: None,
235 }),
236 ) => {
237 PaceTimeFrame::DateRange(
239 TimeRangeOptions::builder()
240 .start(PaceDateTime::try_from((from.to_owned(), time_zone))?.start_of_day()?)
241 .build(),
242 )
243 }
244 (
245 None,
246 Some(DateFlags {
247 date: None,
248 from: None,
249 to: Some(to),
250 }),
251 ) => {
252 PaceTimeFrame::DateRange(
254 TimeRangeOptions::builder()
255 .end(PaceDateTime::try_from((to.to_owned(), time_zone))?.end_of_day()?)
256 .build(),
257 )
258 }
259 (
260 None,
261 Some(DateFlags {
262 date: None,
263 from: Some(from),
264 to: Some(to),
265 }),
266 ) => {
267 PaceTimeFrame::DateRange(
269 TimeRangeOptions::builder()
270 .start(PaceDateTime::try_from((from.to_owned(), time_zone))?.start_of_day()?)
271 .end(PaceDateTime::try_from((to.to_owned(), time_zone))?.end_of_day()?)
272 .build(),
273 )
274 }
275 _ => PaceTimeFrame::default(),
276 };
277
278 debug!("Converted Time frame: {:?}", time_frame);
279
280 Ok(time_frame)
281}
282
283#[cfg(test)]
284mod tests {
285
286 use crate::flags::TimeFlags;
287
288 use super::*;
289
290 use eyre::Result;
291
292 #[test]
293 fn test_get_time_frame_from_flags_today_passes() -> Result<()> {
294 let time_flags = TimeFlags::Today;
295
296 let result = PaceTimeFrame::try_from(&time_flags)?;
297
298 assert_eq!(result, PaceTimeFrame::Today);
299
300 Ok(())
301 }
302}