@@ -142,24 +142,23 @@ impl FormulaScorer<'_> {
142142 Ok ( Haversine :: distance ( ( * origin) . into ( ) , value. into ( ) ) )
143143 }
144144 ParsedExpression :: DateTime ( dt_expr) => {
145- match dt_expr {
146- // Convert from i64 to f64.
147- // f64's 53 bits of sign + mantissa for microseconds means a span of exact equivalence of
148- // about 285 years, after which precision starts dropping
149- DateTimeExpression :: Constant ( dt) => Ok ( dt. timestamp ( ) as PreciseScore ) ,
145+ let datetime = match dt_expr {
146+ DateTimeExpression :: Constant ( dt) => * dt,
150147 DateTimeExpression :: PayloadVariable ( json_path) => {
151- let datetime =
152- self . get_parsed_payload_value ( json_path, point_id, |value| {
153- value
154- // datetime index also returns the display impl of datetime which is a string
155- . as_str ( )
156- . ok_or ( "value is not a string" ) ?
157- . parse :: < DateTimePayloadType > ( )
158- . map_err ( |e| e. to_string ( ) )
159- } ) ?;
160- Ok ( datetime. timestamp ( ) as PreciseScore )
148+ self . get_parsed_payload_value ( json_path, point_id, |value| {
149+ value
150+ // datetime index also returns the display impl of datetime which is a string
151+ . as_str ( )
152+ . ok_or ( "value is not a string" ) ?
153+ . parse :: < DateTimePayloadType > ( )
154+ . map_err ( |e| e. to_string ( ) )
155+ } ) ?
161156 }
162- }
157+ } ;
158+ // Convert from i64 to f64.
159+ // f64's 53 bits of sign + mantissa for microseconds means a span of exact equivalence of
160+ // about 285 years, after which precision starts dropping
161+ Ok ( datetime. timestamp ( ) as PreciseScore )
163162 }
164163 ParsedExpression :: Mult ( expressions) => {
165164 let mut product = 1.0 ;
@@ -320,6 +319,7 @@ mod tests {
320319 const NO_VALUE_FIELD_NAME : & str = "no_number" ;
321320 const GEO_FIELD_NAME : & str = "geo_point" ;
322321 const NO_VALUE_GEO_POINT : & str = "no_value_geo_point" ;
322+ const NO_VALUE_DATETIME : & str = "no_value_datetime" ;
323323
324324 // self_cell just to be able to create FormulaScorer with a "reference" to fixture scores
325325 self_cell:: self_cell!(
@@ -440,7 +440,26 @@ mod tests {
440440 } )
441441 ) ]
442442 // geo distance with default value
443- #[ case( ParsedExpression :: new_geo_distance( GeoPoint { lat: 25.717877679163667 , lon: -100.43383200156751 } , JsonPath :: new( NO_VALUE_GEO_POINT ) ) , Ok ( 90951.3 ) ) ]
443+ #[ case( ParsedExpression :: new_geo_distance( GeoPoint { lat: 25.717877679163667 , lon: -100.43383200156751 } , JsonPath :: new( NO_VALUE_GEO_POINT ) ) , Ok ( 90951.29600298218 ) ) ]
444+ // datetime expression constant
445+ #[ case(
446+ ParsedExpression :: DateTime ( DateTimeExpression :: Constant ( "2025-03-18" . parse( ) . unwrap( ) ) ) ,
447+ Ok ( "2025-03-18" . parse:: <DateTimePayloadType >( ) . unwrap( ) . timestamp( ) as PreciseScore )
448+ ) ]
449+ // datetime expression with payload variable that doesn't exist in payload and no default
450+ #[ case(
451+ ParsedExpression :: DateTime ( DateTimeExpression :: PayloadVariable ( JsonPath :: new( "missing_datetime" ) ) ) ,
452+ Err ( OperationError :: VariableTypeError {
453+ field_name: JsonPath :: new( "missing_datetime" ) ,
454+ expected_type: DateTimePayloadType :: friendly_name( ) . to_string( ) ,
455+ description: "No value found in a payload nor defaults" . to_string( ) ,
456+ } )
457+ ) ]
458+ // datetime expression with payload variable that doesn't exist in payload but has default
459+ #[ case(
460+ ParsedExpression :: DateTime ( DateTimeExpression :: PayloadVariable ( JsonPath :: new( NO_VALUE_DATETIME ) ) ) ,
461+ Ok ( "2025-03-19T12:00:00" . parse:: <DateTimePayloadType >( ) . unwrap( ) . timestamp( ) as PreciseScore )
462+ ) ]
444463 #[ test]
445464 fn test_default_values (
446465 #[ case] expr : ParsedExpression ,
@@ -456,6 +475,10 @@ mod tests {
456475 VariableId :: Payload ( JsonPath :: new ( NO_VALUE_GEO_POINT ) ) ,
457476 json ! ( { "lat" : 25.0 , "lon" : -100.0 } ) ,
458477 ) ,
478+ (
479+ VariableId :: Payload ( JsonPath :: new ( NO_VALUE_DATETIME ) ) ,
480+ json ! ( "2025-03-19T12:00:00" ) ,
481+ ) ,
459482 ]
460483 . into_iter ( )
461484 . collect ( ) ;
0 commit comments