@@ -132,16 +132,21 @@ impl Formula<'_> {
132
132
let date = Self :: datestring_to_naivedate ( & date, & rule_name) ?;
133
133
let date = Self :: shift_months ( date, num) ;
134
134
let last_day = Self :: last_day_of_month ( date. year ( ) , date. month ( ) ) ;
135
- NaiveDate :: from_ymd ( date. year ( ) , date. month ( ) , last_day)
135
+ NaiveDate :: from_ymd_opt ( date. year ( ) , date. month ( ) , last_day)
136
136
}
137
137
( Expr :: Date ( date) , Expr :: Number ( num) ) => {
138
138
let date = Self :: shift_months ( date, num) ;
139
139
let last_day = Self :: last_day_of_month ( date. year ( ) , date. month ( ) ) ;
140
- NaiveDate :: from_ymd ( date. year ( ) , date. month ( ) , last_day)
140
+ NaiveDate :: from_ymd_opt ( date. year ( ) , date. month ( ) , last_day)
141
141
}
142
142
_ => return Err ( Error :: Parser ( rule_name) ) ,
143
143
} ;
144
144
145
+ let date = match date {
146
+ None => return Err ( Error :: Parser ( rule_name) ) ,
147
+ Some ( v) => v,
148
+ } ;
149
+
145
150
Ok ( Expr :: Date ( date) )
146
151
}
147
152
@@ -180,7 +185,7 @@ impl Formula<'_> {
180
185
_ => return Err ( Error :: Parser ( rule_name) ) ,
181
186
} ;
182
187
183
- Ok ( Expr :: Number ( days as f64 ) )
188
+ Ok ( Expr :: Number ( days) )
184
189
}
185
190
186
191
pub ( crate ) fn parse_day ( pair : Pair < Rule > ) -> Result < Expr > {
@@ -227,7 +232,11 @@ impl Formula<'_> {
227
232
let second = Self :: get_formula ( & mut args, & rule_name) ?;
228
233
let time = match ( hour, minute, second) {
229
234
( Expr :: Number ( hour) , Expr :: Number ( minute) , Expr :: Number ( second) ) => {
230
- Expr :: Time ( NaiveTime :: from_hms ( hour as u32 , minute as u32 , second as u32 ) )
235
+ let time = match NaiveTime :: from_hms_opt ( hour as u32 , minute as u32 , second as u32 ) {
236
+ None => return Err ( Error :: Parser ( rule_name) ) ,
237
+ Some ( v) => v,
238
+ } ;
239
+ Expr :: Time ( time)
231
240
}
232
241
_ => return Err ( Error :: Parser ( rule_name) ) ,
233
242
} ;
@@ -242,7 +251,11 @@ impl Formula<'_> {
242
251
let day = Self :: get_formula ( & mut args, & rule_name) ?;
243
252
let date = match ( year, month, day) {
244
253
( Expr :: Number ( year) , Expr :: Number ( month) , Expr :: Number ( day) ) => {
245
- Expr :: Date ( NaiveDate :: from_ymd ( year as i32 , month as u32 , day as u32 ) )
254
+ let date = match NaiveDate :: from_ymd_opt ( year as i32 , month as u32 , day as u32 ) {
255
+ None => return Err ( Error :: Parser ( rule_name) ) ,
256
+ Some ( v) => v,
257
+ } ;
258
+ Expr :: Date ( date)
246
259
}
247
260
_ => return Err ( Error :: Parser ( rule_name) ) ,
248
261
} ;
@@ -256,7 +269,7 @@ impl Formula<'_> {
256
269
. collect :: < std:: result:: Result < Vec < _ > , _ > > ( )
257
270
. map_err ( |_| Error :: Parser ( rule_name. to_owned ( ) ) ) ?;
258
271
#[ allow( clippy:: cast_possible_wrap) ]
259
- Ok ( NaiveDate :: from_ymd ( mdy[ 2 ] as i32 , mdy[ 0 ] , mdy[ 1 ] ) )
272
+ NaiveDate :: from_ymd_opt ( mdy[ 2 ] as i32 , mdy[ 0 ] , mdy[ 1 ] ) . ok_or_else ( || Error :: Parser ( rule_name . to_owned ( ) ) )
260
273
}
261
274
262
275
fn timestring_to_naivetime ( timestring : & str , rule_name : & str ) -> Result < NaiveTime > {
@@ -267,14 +280,15 @@ impl Formula<'_> {
267
280
. map ( str:: parse)
268
281
. collect :: < std:: result:: Result < Vec < _ > , _ > > ( )
269
282
. map_err ( |_| Error :: Parser ( rule_name. to_owned ( ) ) ) ?;
270
- Ok ( NaiveTime :: from_hms ( hms[ 0 ] , hms[ 1 ] , hms[ 2 ] ) )
283
+ NaiveTime :: from_hms_opt ( hms[ 0 ] , hms[ 1 ] , hms[ 2 ] ) . ok_or_else ( || Error :: Parser ( rule_name . to_owned ( ) ) )
271
284
}
272
285
273
286
fn last_day_of_month ( year : i32 , month : u32 ) -> u32 {
274
287
NaiveDate :: from_ymd_opt ( year, month + 1 , 1 )
275
- . unwrap_or_else ( || NaiveDate :: from_ymd ( year + 1 , 1 , 1 ) )
276
- . pred ( )
277
- . day ( )
288
+ . ok_or_else ( || NaiveDate :: from_ymd_opt ( year + 1 , 1 , 1 ) )
289
+ . map ( |v| v. pred_opt ( ) . map ( |v| v. day ( ) ) )
290
+ . expect ( "A valid date" )
291
+ . expect ( "A valid date" )
278
292
}
279
293
280
294
fn shift_months ( date : NaiveDate , months : f64 ) -> NaiveDate {
@@ -287,7 +301,7 @@ impl Formula<'_> {
287
301
let last_day = Self :: last_day_of_month ( year, month) ;
288
302
let day = if day > last_day { last_day } else { day } ;
289
303
290
- NaiveDate :: from_ymd ( year, month, day)
304
+ NaiveDate :: from_ymd_opt ( year, month, day) . expect ( "A valid date" )
291
305
}
292
306
}
293
307
@@ -301,11 +315,11 @@ mod tests {
301
315
fn test_parse_date_and_time_types ( ) {
302
316
let formula = Formula :: new ( "=DATE(2020,2,3)" ) . unwrap ( ) ;
303
317
let value = formula. parse ( ) . unwrap ( ) ;
304
- assert_eq ! ( value, Expr :: Date ( NaiveDate :: from_ymd ( 2020 , 2 , 3 ) ) ) ;
318
+ assert_eq ! ( value, Expr :: Date ( NaiveDate :: from_ymd_opt ( 2020 , 2 , 3 ) . unwrap ( ) ) ) ;
305
319
306
320
let formula = Formula :: new ( "=DATE(YEAR('1/30/2020'),MONTH('1/30/2020'),DAY('1/30/2020'))" . trim ( ) ) . unwrap ( ) ;
307
321
let value = formula. parse ( ) . unwrap ( ) ;
308
- assert_eq ! ( value, Expr :: Date ( NaiveDate :: from_ymd ( 2020 , 1 , 30 ) ) ) ;
322
+ assert_eq ! ( value, Expr :: Date ( NaiveDate :: from_ymd_opt ( 2020 , 1 , 30 ) . unwrap ( ) ) ) ;
309
323
310
324
let formula = Formula :: new ( "=YEAR('1/30/2020')" ) . unwrap ( ) ;
311
325
let value = formula. parse ( ) . unwrap ( ) ;
@@ -321,7 +335,7 @@ mod tests {
321
335
322
336
let formula = Formula :: new ( "=DATEVALUE('1/30/2020')" ) . unwrap ( ) ;
323
337
let value = formula. parse ( ) . unwrap ( ) ;
324
- assert_eq ! ( value, Expr :: Date ( NaiveDate :: from_ymd ( 2020 , 1 , 30 ) ) ) ;
338
+ assert_eq ! ( value, Expr :: Date ( NaiveDate :: from_ymd_opt ( 2020 , 1 , 30 ) . unwrap ( ) ) ) ;
325
339
326
340
let formula = Formula :: new ( "=DAYS('3/30/2020', '1/30/2020')" ) . unwrap ( ) ;
327
341
let value = formula. parse ( ) . unwrap ( ) ;
@@ -337,19 +351,19 @@ mod tests {
337
351
338
352
let formula = Formula :: new ( "=EDATE('1/30/2020', 5)" ) . unwrap ( ) ;
339
353
let value = formula. parse ( ) . unwrap ( ) ;
340
- assert_eq ! ( value, Expr :: Date ( NaiveDate :: from_ymd ( 2020 , 6 , 30 ) ) ) ;
354
+ assert_eq ! ( value, Expr :: Date ( NaiveDate :: from_ymd_opt ( 2020 , 6 , 30 ) . unwrap ( ) ) ) ;
341
355
342
356
let formula = Formula :: new ( "=EDATE(DATE(2020,8,25),27)" ) . unwrap ( ) ;
343
357
let value = formula. parse ( ) . unwrap ( ) ;
344
- assert_eq ! ( value, Expr :: Date ( NaiveDate :: from_ymd ( 2022 , 11 , 25 ) ) ) ;
358
+ assert_eq ! ( value, Expr :: Date ( NaiveDate :: from_ymd_opt ( 2022 , 11 , 25 ) . unwrap ( ) ) ) ;
345
359
346
360
let formula = Formula :: new ( "=EOMONTH('1/20/2020', 5)" ) . unwrap ( ) ;
347
361
let value = formula. parse ( ) . unwrap ( ) ;
348
- assert_eq ! ( value, Expr :: Date ( NaiveDate :: from_ymd ( 2020 , 6 , 30 ) ) ) ;
362
+ assert_eq ! ( value, Expr :: Date ( NaiveDate :: from_ymd_opt ( 2020 , 6 , 30 ) . unwrap ( ) ) ) ;
349
363
350
364
let formula = Formula :: new ( "=EOMONTH(DATE(2020,8,31),27)" ) . unwrap ( ) ;
351
365
let value = formula. parse ( ) . unwrap ( ) ;
352
- assert_eq ! ( value, Expr :: Date ( NaiveDate :: from_ymd ( 2022 , 11 , 30 ) ) ) ;
366
+ assert_eq ! ( value, Expr :: Date ( NaiveDate :: from_ymd_opt ( 2022 , 11 , 30 ) . unwrap ( ) ) ) ;
353
367
354
368
let formula = Formula :: new ( "=HOUR('02:30:00')" ) . unwrap ( ) ;
355
369
let value = formula. parse ( ) . unwrap ( ) ;
@@ -369,11 +383,11 @@ mod tests {
369
383
370
384
let formula = Formula :: new ( "=TIME(2,30,0)" ) . unwrap ( ) ;
371
385
let value = formula. parse ( ) . unwrap ( ) ;
372
- assert_eq ! ( value, Expr :: Time ( NaiveTime :: from_hms ( 2 , 30 , 0 ) ) ) ;
386
+ assert_eq ! ( value, Expr :: Time ( NaiveTime :: from_hms_opt ( 2 , 30 , 0 ) . unwrap ( ) ) ) ;
373
387
374
388
let formula = Formula :: new ( "=TIMEVALUE('02:30:00')" ) . unwrap ( ) ;
375
389
let value = formula. parse ( ) . unwrap ( ) ;
376
- assert_eq ! ( value, Expr :: Time ( NaiveTime :: from_hms ( 2 , 30 , 0 ) ) ) ;
390
+ assert_eq ! ( value, Expr :: Time ( NaiveTime :: from_hms_opt ( 2 , 30 , 0 ) . unwrap ( ) ) ) ;
377
391
378
392
let formula = Formula :: new ( "=WEEKDAY(DATE(2020,1,1))" ) . unwrap ( ) ;
379
393
let value = formula. parse ( ) . unwrap ( ) ;
0 commit comments