4949 return Value :: Null ;
5050 }
5151
52- let value = values. next ( ) . unwrap ( ) ;
52+ let Some ( value) = values. next ( ) else {
53+ return Value :: Null ;
54+ } ;
5355 let value = value. as_value_ref ( ) ;
5456 let format_str = if matches ! (
5557 value,
@@ -80,11 +82,15 @@ where
8082{
8183 let values = values. into_iter ( ) ;
8284 if values. len ( ) == 0 {
83- let now = parse_naive_date_time ( Value :: build_text ( "now" ) ) . unwrap ( ) ;
85+ let Some ( now) = parse_naive_date_time ( Value :: build_text ( "now" ) ) else {
86+ return Value :: Null ;
87+ } ;
8488 return format_dt ( now, output_type, false ) ;
8589 }
8690 let mut values = values. peekable ( ) ;
87- let first = values. peek ( ) . unwrap ( ) ;
91+ let Some ( first) = values. peek ( ) else {
92+ return Value :: Null ;
93+ } ;
8894 if let Some ( mut dt) = parse_naive_date_time ( first) {
8995 // if successful, treat subsequent entries as modifiers
9096 modify_dt ( & mut dt, values. skip ( 1 ) , output_type)
@@ -231,18 +237,19 @@ fn apply_modifier(dt: &mut NaiveDateTime, modifier: &str, n_floor: &mut i64) ->
231237 }
232238 Modifier :: StartOfMonth => {
233239 * dt = NaiveDate :: from_ymd_opt ( dt. year ( ) , dt. month ( ) , 1 )
234- . unwrap ( )
235- . and_hms_opt ( 0 , 0 , 0 )
236- . unwrap ( ) ;
240+ . and_then ( |d| d. and_hms_opt ( 0 , 0 , 0 ) )
241+ . ok_or_else ( || InvalidModifier ( "failed to construct start of month" . to_string ( ) ) ) ?;
237242 }
238243 Modifier :: StartOfYear => {
239244 * dt = NaiveDate :: from_ymd_opt ( dt. year ( ) , 1 , 1 )
240- . unwrap ( )
241- . and_hms_opt ( 0 , 0 , 0 )
242- . unwrap ( ) ;
245+ . and_then ( |d| d. and_hms_opt ( 0 , 0 , 0 ) )
246+ . ok_or_else ( || InvalidModifier ( "failed to construct start of year" . to_string ( ) ) ) ?;
243247 }
244248 Modifier :: StartOfDay => {
245- * dt = dt. date ( ) . and_hms_opt ( 0 , 0 , 0 ) . unwrap ( ) ;
249+ * dt = dt
250+ . date ( )
251+ . and_hms_opt ( 0 , 0 , 0 )
252+ . ok_or_else ( || InvalidModifier ( "failed to construct start of day" . to_string ( ) ) ) ?;
246253 }
247254 Modifier :: Weekday ( day) => {
248255 let current_day = dt. weekday ( ) . num_days_from_sunday ( ) ;
@@ -259,11 +266,18 @@ fn apply_modifier(dt: &mut NaiveDateTime, modifier: &str, n_floor: &mut i64) ->
259266 }
260267 Modifier :: Utc => {
261268 // TODO: handle datetime('now', 'utc') no-op
262- let local_dt = chrono:: Local . from_local_datetime ( dt) . unwrap ( ) ;
269+ let local_dt = chrono:: Local
270+ . from_local_datetime ( dt)
271+ . single ( )
272+ . ok_or_else ( || {
273+ InvalidModifier ( "ambiguous local datetime during DST transition" . to_string ( ) )
274+ } ) ?;
263275 * dt = local_dt. with_timezone ( & Utc ) . naive_utc ( ) ;
264276 }
265277 Modifier :: Subsec => {
266- * dt = dt. with_nanosecond ( dt. nanosecond ( ) ) . unwrap ( ) ;
278+ * dt = dt
279+ . with_nanosecond ( dt. nanosecond ( ) )
280+ . ok_or_else ( || InvalidModifier ( "failed to set nanoseconds" . to_string ( ) ) ) ?;
267281 return Ok ( true ) ;
268282 }
269283 }
@@ -482,7 +496,7 @@ fn get_date_time_from_time_value_string(value: &str) -> Option<NaiveDateTime> {
482496
483497 // First, try to parse as date-only format
484498 if let Ok ( date) = NaiveDate :: parse_from_str ( value, date_only_format) {
485- return Some ( date . and_time ( NaiveTime :: from_hms_opt ( 0 , 0 , 0 ) . unwrap ( ) ) ) ;
499+ return NaiveTime :: from_hms_opt ( 0 , 0 , 0 ) . map ( |time| date . and_time ( time ) ) ;
486500 }
487501
488502 for format in & datetime_formats {
@@ -598,10 +612,9 @@ fn is_leap_second(dt: &NaiveDateTime) -> bool {
598612
599613fn get_max_datetime_exclusive ( ) -> NaiveDateTime {
600614 // The maximum date in SQLite is 9999-12-31
601- NaiveDateTime :: new (
602- NaiveDate :: from_ymd_opt ( 10000 , 1 , 1 ) . unwrap ( ) ,
603- NaiveTime :: from_hms_milli_opt ( 00 , 00 , 00 , 000 ) . unwrap ( ) ,
604- )
615+ let date = NaiveDate :: from_ymd_opt ( 10000 , 1 , 1 ) . expect ( "10000-01-01 is valid" ) ;
616+ let time = NaiveTime :: from_hms_milli_opt ( 00 , 00 , 00 , 000 ) . expect ( "00:00:00.000 is valid" ) ;
617+ NaiveDateTime :: new ( date, time)
605618}
606619
607620/// Modifier doc https://www.sqlite.org/lang_datefunc.html#modifiers
@@ -824,8 +837,15 @@ where
824837 return Value :: Null ;
825838 }
826839
827- let start = parse_naive_date_time ( values. next ( ) . unwrap ( ) ) ;
828- let end = parse_naive_date_time ( values. next ( ) . unwrap ( ) ) ;
840+ let Some ( start_val) = values. next ( ) else {
841+ return Value :: Null ;
842+ } ;
843+ let Some ( end_val) = values. next ( ) else {
844+ return Value :: Null ;
845+ } ;
846+
847+ let start = parse_naive_date_time ( start_val) ;
848+ let end = parse_naive_date_time ( end_val) ;
829849
830850 match ( start, end) {
831851 ( Some ( start) , Some ( end) ) => {
0 commit comments