@@ -279,25 +279,37 @@ fn matches_any_pattern(field_name: &str, field_patterns: &[FieldPattern]) -> boo
279279enum FieldPattern {
280280 Match { field : String } ,
281281 Wildcard { prefix : String , suffix : String } ,
282+ Contains { infix : String } ,
282283}
283284
284285impl FromStr for FieldPattern {
285286 type Err = crate :: SearchError ;
286287
287288 fn from_str ( field_pattern : & str ) -> crate :: Result < Self > {
288- match field_pattern. find ( '*' ) {
289+ if field_pattern. starts_with ( '*' ) && field_pattern. ends_with ( '*' ) {
290+ let infix = field_pattern. trim_matches ( '*' ) . to_string ( ) ;
291+ if infix. contains ( '*' ) {
292+ return Err ( crate :: SearchError :: InvalidArgument ( format ! (
293+ "invalid field pattern `{field_pattern}`: 'contains' type patterns can't have a wildcard in the middle"
294+ ) ) ) ;
295+ }
296+ return Ok ( Self :: Contains { infix } ) ;
297+ }
298+
299+ match field_pattern. split_once ( '*' ) {
289300 None => Ok ( FieldPattern :: Match {
290301 field : field_pattern. to_string ( ) ,
291302 } ) ,
292- Some ( pos) => {
293- let prefix = field_pattern[ ..pos] . to_string ( ) ;
294- let suffix = field_pattern[ pos + 1 ..] . to_string ( ) ;
303+ Some ( ( prefix, suffix) ) => {
295304 if suffix. contains ( "*" ) {
296305 return Err ( crate :: SearchError :: InvalidArgument ( format ! (
297306 "invalid field pattern `{field_pattern}`: we only support one wildcard"
298307 ) ) ) ;
299308 }
300- Ok ( FieldPattern :: Wildcard { prefix, suffix } )
309+ Ok ( FieldPattern :: Wildcard {
310+ prefix : prefix. to_string ( ) ,
311+ suffix : suffix. to_string ( ) ,
312+ } )
301313 }
302314 }
303315 }
@@ -310,6 +322,7 @@ impl FieldPattern {
310322 FieldPattern :: Wildcard { prefix, suffix } => {
311323 field_name. starts_with ( prefix) && field_name. ends_with ( suffix)
312324 }
325+ FieldPattern :: Contains { infix } => field_name. contains ( infix) ,
313326 }
314327 }
315328}
@@ -331,7 +344,7 @@ pub async fn leaf_list_fields(
331344
332345 // If no splits, return empty response
333346 if split_ids. is_empty ( ) {
334- return Ok ( ListFieldsResponse { fields : Vec :: new ( ) } ) ;
347+ return Ok ( ListFieldsResponse :: default ( ) ) ;
335348 }
336349
337350 // Get fields from all splits
@@ -1032,6 +1045,15 @@ mod tests {
10321045 assert ! ( !inner_pattern. matches( "tito" ) ) ;
10331046 assert ! ( inner_pattern. matches( "towhateverti" ) ) ;
10341047
1048+ let contains_pattern = FieldPattern :: from_str ( "*my_field*" ) . unwrap ( ) ;
1049+ assert ! ( !contains_pattern. matches( "" ) ) ;
1050+ assert ! ( !contains_pattern. matches( "my_fiel" ) ) ;
1051+ assert ! ( contains_pattern. matches( "my_field" ) ) ;
1052+ assert ! ( contains_pattern. matches( "prefix_my_field" ) ) ;
1053+ assert ! ( contains_pattern. matches( "my_field_suffix" ) ) ;
1054+ assert ! ( contains_pattern. matches( "prefix_my_field_suffix" ) ) ;
1055+
10351056 assert ! ( FieldPattern :: from_str( "to**" ) . is_err( ) ) ;
1057+ assert ! ( FieldPattern :: from_str( "*a*b*" ) . is_err( ) ) ;
10361058 }
10371059}
0 commit comments