1
+ use chrono:: { Local , NaiveDateTime } ;
1
2
use human_date_parser:: { from_human_time, ParseResult } ;
2
3
use regex:: Regex ;
3
4
use sea_orm:: entity:: ColumnDef ;
@@ -105,6 +106,7 @@ impl Query {
105
106
..
106
107
} => context
107
108
. values ( )
109
+ . filter ( |v| matches ! ( v, Value :: String ( _) ) )
108
110
. any ( |field| vs. iter ( ) . any ( |v| field. contains ( v) ) ) ,
109
111
_ => false ,
110
112
}
@@ -245,6 +247,7 @@ impl Value<'_> {
245
247
pub fn contains ( & self , pat : & str ) -> bool {
246
248
match self {
247
249
Self :: String ( s) => s. contains ( pat) ,
250
+ Self :: Date ( d) => d. to_string ( ) . contains ( pat) ,
248
251
_ => false ,
249
252
}
250
253
}
@@ -262,7 +265,25 @@ impl PartialEq<String> for Value<'_> {
262
265
Ok ( i) => v. eq ( & i) ,
263
266
_ => false ,
264
267
} ,
265
- Self :: Date ( _) => false , // impractical, given the granularity
268
+ Self :: Date ( v) => match from_human_time ( & v. to_string ( ) ) {
269
+ Ok ( ParseResult :: DateTime ( field) ) => match from_human_time ( rhs) {
270
+ Ok ( ParseResult :: DateTime ( other) ) => field. eq ( & other) ,
271
+ Ok ( ParseResult :: Date ( d) ) => {
272
+ let other = NaiveDateTime :: new ( d, field. time ( ) )
273
+ . and_local_timezone ( Local )
274
+ . unwrap ( ) ;
275
+ field. eq ( & other)
276
+ }
277
+ Ok ( ParseResult :: Time ( t) ) => {
278
+ let other = NaiveDateTime :: new ( field. date_naive ( ) , t)
279
+ . and_local_timezone ( Local )
280
+ . unwrap ( ) ;
281
+ field. eq ( & other)
282
+ }
283
+ _ => false ,
284
+ } ,
285
+ _ => false ,
286
+ } ,
266
287
}
267
288
}
268
289
}
@@ -280,13 +301,22 @@ impl PartialOrd<String> for Value<'_> {
280
301
_ => None ,
281
302
} ,
282
303
Self :: Date ( v) => match from_human_time ( & v. to_string ( ) ) {
283
- Ok ( ParseResult :: DateTime ( field) ) => {
284
- if let Ok ( ParseResult :: DateTime ( other) ) = from_human_time ( rhs) {
304
+ Ok ( ParseResult :: DateTime ( field) ) => match from_human_time ( rhs) {
305
+ Ok ( ParseResult :: DateTime ( other) ) => field. partial_cmp ( & other) ,
306
+ Ok ( ParseResult :: Date ( d) ) => {
307
+ let other = NaiveDateTime :: new ( d, field. time ( ) )
308
+ . and_local_timezone ( Local )
309
+ . unwrap ( ) ;
285
310
field. partial_cmp ( & other)
286
- } else {
287
- None
288
311
}
289
- }
312
+ Ok ( ParseResult :: Time ( t) ) => {
313
+ let other = NaiveDateTime :: new ( field. date_naive ( ) , t)
314
+ . and_local_timezone ( Local )
315
+ . unwrap ( ) ;
316
+ field. partial_cmp ( & other)
317
+ }
318
+ _ => None ,
319
+ } ,
290
320
_ => None ,
291
321
} ,
292
322
}
@@ -1132,20 +1162,37 @@ mod tests {
1132
1162
1133
1163
#[ test( tokio:: test) ]
1134
1164
async fn apply_to_context ( ) -> Result < ( ) , anyhow:: Error > {
1165
+ use time:: format_description:: well_known:: Rfc2822 ;
1135
1166
let now = time:: OffsetDateTime :: now_utc ( ) ;
1167
+ let then = OffsetDateTime :: parse ( "Sat, 12 Jun 1993 13:25:19 GMT" , & Rfc2822 ) ?;
1136
1168
let context = HashMap :: from ( [
1137
1169
( "id" , Value :: String ( "foo" ) ) ,
1138
1170
( "count" , Value :: Int ( 42 ) ) ,
1139
1171
( "score" , Value :: Float ( 6.66 ) ) ,
1172
+ ( "detected" , Value :: Date ( & then) ) ,
1140
1173
( "published" , Value :: Date ( & now) ) ,
1141
1174
] ) ;
1142
1175
assert ! ( q( "oo|aa|bb&count<100&count>10&id=foo" ) . apply( & context) ) ;
1143
1176
assert ! ( q( "score=6.66" ) . apply( & context) ) ;
1144
1177
assert ! ( q( "count>=42&count<=42" ) . apply( & context) ) ;
1145
- assert ! ( q( "published>2 days ago&published<in 1 week" ) . apply( & context) ) ;
1178
+ assert ! ( q( "published>2 days ago&published<next week" ) . apply( & context) ) ;
1179
+
1180
+ assert ! ( q( "detected=1993-06-12" ) . apply( & context) ) ;
1181
+ assert ! ( q( "detected>13:20:00" ) . apply( & context) ) ;
1182
+ assert ! ( q( "detected~1993" ) . apply( & context) ) ;
1183
+ assert ! ( !q( "1993" ) . apply( & context) ) ;
1184
+
1185
+ assert ! ( q( & format!( "published={}" , now) ) . apply( & context) ) ;
1186
+ assert ! ( q( & format!( "published={}" , now. date( ) ) ) . apply( & context) ) ;
1187
+ assert ! ( q( & format!( "published={}" , now. time( ) ) ) . apply( & context) ) ;
1188
+ assert ! ( q( & format!( "published>=today {}" , now. time( ) ) ) . apply( & context) ) ;
1189
+ assert ! ( q( & format!( "published>={}" , now) ) . apply( & context) ) ;
1190
+ assert ! ( q( & format!( "published<={}" , now. date( ) ) ) . apply( & context) ) ;
1191
+ assert ! ( q( & format!( "published~{}" , now. time( ) ) ) . apply( & context) ) ;
1146
1192
1147
1193
Ok ( ( ) )
1148
1194
}
1195
+
1149
1196
/////////////////////////////////////////////////////////////////////////
1150
1197
// Test helpers
1151
1198
/////////////////////////////////////////////////////////////////////////
0 commit comments