2
2
//!
3
3
//! Requires the `time_trigger` feature.
4
4
5
- #[ cfg( test) ]
6
- use chrono:: NaiveDateTime ;
7
5
use chrono:: { DateTime , Datelike , Duration , Local , TimeZone , Timelike } ;
8
6
#[ cfg( test) ]
9
7
use mock_instant:: { SystemTime , UNIX_EPOCH } ;
@@ -13,11 +11,18 @@ use serde::de;
13
11
#[ cfg( feature = "config_parsing" ) ]
14
12
use std:: fmt;
15
13
use std:: sync:: RwLock ;
14
+ use thiserror:: Error ;
16
15
17
16
use crate :: append:: rolling_file:: { policy:: compound:: trigger:: Trigger , LogFile } ;
18
17
#[ cfg( feature = "config_parsing" ) ]
19
18
use crate :: config:: { Deserialize , Deserializers } ;
20
19
20
+ macro_rules! try_from {
21
+ ( $func: ident, $para: expr, $interval: expr) => {
22
+ Duration :: $func( $para) . ok_or( TimeTrigerError :: TooLargeInterval ( $interval) ) ?
23
+ } ;
24
+ }
25
+
21
26
#[ cfg( feature = "config_parsing" ) ]
22
27
/// Configuration for the time trigger.
23
28
#[ derive( Copy , Clone , Eq , PartialEq , Hash , Debug , Default , serde:: Deserialize ) ]
@@ -73,6 +78,12 @@ impl Default for TimeTriggerInterval {
73
78
}
74
79
}
75
80
81
+ #[ derive( Debug , Error ) ]
82
+ enum TimeTrigerError {
83
+ #[ error( "The integer value {0:?} for the specified time trigger interval is too large, it must be less than 9,223,372,036,854,775,807 seconds." ) ]
84
+ TooLargeInterval ( TimeTriggerInterval ) ,
85
+ }
86
+
76
87
#[ cfg( feature = "config_parsing" ) ]
77
88
impl < ' de > serde:: Deserialize < ' de > for TimeTriggerInterval {
78
89
fn deserialize < D > ( d : D ) -> Result < Self , D :: Error >
@@ -181,18 +192,19 @@ impl TimeTrigger {
181
192
let now: std:: time:: Duration = SystemTime :: now ( )
182
193
. duration_since ( UNIX_EPOCH )
183
194
. expect ( "system time before Unix epoch" ) ;
184
- NaiveDateTime :: from_timestamp_opt ( now. as_secs ( ) as i64 , now. subsec_nanos ( ) )
195
+ DateTime :: from_timestamp ( now. as_secs ( ) as i64 , now. subsec_nanos ( ) )
185
196
. unwrap ( )
197
+ . naive_local ( )
186
198
. and_local_timezone ( Local )
187
199
. unwrap ( )
188
200
} ;
189
201
190
202
#[ cfg( not( test) ) ]
191
203
let current = Local :: now ( ) ;
192
- let next_time = TimeTrigger :: get_next_time ( current, config. interval , config. modulate ) ;
204
+ let next_time = TimeTrigger :: get_next_time ( current, config. interval , config. modulate ) . unwrap ( ) ;
193
205
let next_roll_time = if config. max_random_delay > 0 {
194
206
let random_delay = rand:: thread_rng ( ) . gen_range ( 0 ..config. max_random_delay ) ;
195
- next_time + Duration :: seconds ( random_delay as i64 )
207
+ next_time + Duration :: try_seconds ( random_delay as i64 ) . unwrap_or ( Duration :: try_milliseconds ( i64 :: MAX ) . unwrap ( ) )
196
208
} else {
197
209
next_time
198
210
} ;
@@ -207,13 +219,13 @@ impl TimeTrigger {
207
219
current : DateTime < Local > ,
208
220
interval : TimeTriggerInterval ,
209
221
modulate : bool ,
210
- ) -> DateTime < Local > {
222
+ ) -> Result < DateTime < Local > , TimeTrigerError > {
211
223
let year = current. year ( ) ;
212
224
if let TimeTriggerInterval :: Year ( n) = interval {
213
225
let n = n as i32 ;
214
226
let increment = if modulate { n - year % n } else { n } ;
215
227
let year_new = year + increment;
216
- return Local . with_ymd_and_hms ( year_new, 1 , 1 , 0 , 0 , 0 ) . unwrap ( ) ;
228
+ return Ok ( Local . with_ymd_and_hms ( year_new, 1 , 1 , 0 , 0 , 0 ) . unwrap ( ) ) ;
217
229
}
218
230
219
231
if let TimeTriggerInterval :: Month ( n) = interval {
@@ -224,9 +236,9 @@ impl TimeTrigger {
224
236
let num_months_new = num_months + increment;
225
237
let year_new = ( num_months_new / 12 ) as i32 ;
226
238
let month_new = ( num_months_new) % 12 + 1 ;
227
- return Local
239
+ return Ok ( Local
228
240
. with_ymd_and_hms ( year_new, month_new, 1 , 0 , 0 , 0 )
229
- . unwrap ( ) ;
241
+ . unwrap ( ) ) ;
230
242
}
231
243
232
244
let month = current. month ( ) ;
@@ -236,14 +248,17 @@ impl TimeTrigger {
236
248
let weekday = current. weekday ( ) . num_days_from_monday ( ) as i64 ; // Monday is the first day of the week
237
249
let time = Local . with_ymd_and_hms ( year, month, day, 0 , 0 , 0 ) . unwrap ( ) ;
238
250
let increment = if modulate { n - week0 % n } else { n } ;
239
- return time + Duration :: weeks ( increment) - Duration :: days ( weekday) ;
251
+ let dur =
252
+ try_from ! ( try_weeks, increment, interval) - try_from ! ( try_days, weekday, interval) ;
253
+ return Ok ( time + dur) ;
240
254
}
241
255
242
256
if let TimeTriggerInterval :: Day ( n) = interval {
243
257
let ordinal0 = current. ordinal0 ( ) as i64 ;
244
258
let time = Local . with_ymd_and_hms ( year, month, day, 0 , 0 , 0 ) . unwrap ( ) ;
245
259
let increment = if modulate { n - ordinal0 % n } else { n } ;
246
- return time + Duration :: days ( increment) ;
260
+ let dur = try_from ! ( try_days, increment, interval) ;
261
+ return Ok ( time + dur) ;
247
262
}
248
263
249
264
let hour = current. hour ( ) ;
@@ -252,7 +267,8 @@ impl TimeTrigger {
252
267
. with_ymd_and_hms ( year, month, day, hour, 0 , 0 )
253
268
. unwrap ( ) ;
254
269
let increment = if modulate { n - ( hour as i64 ) % n } else { n } ;
255
- return time + Duration :: hours ( increment) ;
270
+ let dur = try_from ! ( try_hours, increment, interval) ;
271
+ return Ok ( time + dur) ;
256
272
}
257
273
258
274
let min = current. minute ( ) ;
@@ -261,7 +277,8 @@ impl TimeTrigger {
261
277
. with_ymd_and_hms ( year, month, day, hour, min, 0 )
262
278
. unwrap ( ) ;
263
279
let increment = if modulate { n - ( min as i64 ) % n } else { n } ;
264
- return time + Duration :: minutes ( increment) ;
280
+ let dur = try_from ! ( try_minutes, increment, interval) ;
281
+ return Ok ( time + dur) ;
265
282
}
266
283
267
284
let sec = current. second ( ) ;
@@ -270,7 +287,8 @@ impl TimeTrigger {
270
287
. with_ymd_and_hms ( year, month, day, hour, min, sec)
271
288
. unwrap ( ) ;
272
289
let increment = if modulate { n - ( sec as i64 ) % n } else { n } ;
273
- return time + Duration :: seconds ( increment) ;
290
+ let dur = try_from ! ( try_seconds, increment, interval) ;
291
+ return Ok ( time + dur) ;
274
292
}
275
293
panic ! ( "Should not reach here!" ) ;
276
294
}
@@ -283,8 +301,9 @@ impl Trigger for TimeTrigger {
283
301
let now = SystemTime :: now ( )
284
302
. duration_since ( UNIX_EPOCH )
285
303
. expect ( "system time before Unix epoch" ) ;
286
- NaiveDateTime :: from_timestamp_opt ( now. as_secs ( ) as i64 , now. subsec_nanos ( ) )
304
+ DateTime :: from_timestamp ( now. as_secs ( ) as i64 , now. subsec_nanos ( ) )
287
305
. unwrap ( )
306
+ . naive_local ( )
288
307
. and_local_timezone ( Local )
289
308
. unwrap ( )
290
309
} ;
0 commit comments