@@ -272,34 +272,7 @@ fn normalize_value_to_unordered_redactions(
272272 * act = normalize_str_to_unordered_redactions ( act, exp, substitutions) ;
273273 }
274274 ( Array ( act) , Array ( exp) ) => {
275- let mut actual_values = std:: mem:: take ( act) ;
276- let mut expected_values = exp. clone ( ) ;
277- let mut elided = false ;
278- expected_values. retain ( |expected_value| {
279- let mut matched = false ;
280- if expected_value == VALUE_WILDCARD {
281- matched = true ;
282- elided = true ;
283- } else {
284- actual_values. retain ( |actual_value| {
285- if !matched && actual_value == expected_value {
286- matched = true ;
287- false
288- } else {
289- true
290- }
291- } ) ;
292- }
293- if matched {
294- act. push ( expected_value. clone ( ) ) ;
295- }
296- !matched
297- } ) ;
298- if !elided {
299- for actual_value in actual_values {
300- act. push ( actual_value) ;
301- }
302- }
275+ * act = normalize_array_to_unordered_redactions ( act, exp, substitutions) ;
303276 }
304277 ( Object ( act) , Object ( exp) ) => {
305278 let has_key_wildcard =
@@ -324,6 +297,55 @@ fn normalize_value_to_unordered_redactions(
324297 }
325298}
326299
300+ #[ cfg( feature = "structured-data" ) ]
301+ fn normalize_array_to_unordered_redactions (
302+ actual : & [ serde_json:: Value ] ,
303+ expected : & [ serde_json:: Value ] ,
304+ substitutions : & Redactions ,
305+ ) -> Vec < serde_json:: Value > {
306+ if actual == expected {
307+ return actual. to_owned ( ) ;
308+ }
309+
310+ let mut normalized: Vec < serde_json:: Value > = Vec :: new ( ) ;
311+ let mut actual_values = actual. to_owned ( ) ;
312+ let mut expected_values = expected. to_owned ( ) ;
313+ let mut elided = false ;
314+ expected_values. retain ( |expected_value| {
315+ let mut matched = false ;
316+ if expected_value == VALUE_WILDCARD {
317+ matched = true ;
318+ elided = true ;
319+ } else {
320+ actual_values. retain ( |actual_value| {
321+ let mut normalized_actual_value = actual_value. clone ( ) ;
322+ normalize_value_to_unordered_redactions (
323+ & mut normalized_actual_value,
324+ expected_value,
325+ substitutions,
326+ ) ;
327+ if !matched && normalized_actual_value == * expected_value {
328+ matched = true ;
329+ false
330+ } else {
331+ true
332+ }
333+ } ) ;
334+ }
335+ if matched {
336+ normalized. push ( expected_value. clone ( ) ) ;
337+ }
338+ !matched
339+ } ) ;
340+ if !elided {
341+ for actual_value in actual_values {
342+ normalized. push ( actual_value) ;
343+ }
344+ }
345+
346+ normalized
347+ }
348+
327349fn normalize_str_to_unordered_redactions (
328350 actual : & str ,
329351 expected : & str ,
@@ -454,120 +476,124 @@ fn normalize_value_to_redactions(
454476
455477#[ cfg( feature = "structured-data" ) ]
456478fn normalize_array_to_redactions (
457- input : & [ serde_json:: Value ] ,
458- pattern : & [ serde_json:: Value ] ,
479+ actual : & [ serde_json:: Value ] ,
480+ expected : & [ serde_json:: Value ] ,
459481 redactions : & Redactions ,
460482) -> Vec < serde_json:: Value > {
461- if input == pattern {
462- return input . to_vec ( ) ;
483+ if actual == expected {
484+ return actual . to_vec ( ) ;
463485 }
464486
465487 let mut normalized: Vec < serde_json:: Value > = Vec :: new ( ) ;
466- let mut input_index = 0 ;
467- let mut pattern = pattern . iter ( ) . peekable ( ) ;
468- while let Some ( pattern_elem ) = pattern . next ( ) {
469- if pattern_elem == VALUE_WILDCARD {
470- let Some ( next_pattern_elem ) = pattern . peek ( ) else {
488+ let mut actual_index = 0 ;
489+ let mut expected = expected . iter ( ) . peekable ( ) ;
490+ while let Some ( expected_elem ) = expected . next ( ) {
491+ if expected_elem == VALUE_WILDCARD {
492+ let Some ( next_expected_elem ) = expected . peek ( ) else {
471493 // Stop as elide consumes to end
472- normalized. push ( pattern_elem . clone ( ) ) ;
473- input_index = input . len ( ) ;
494+ normalized. push ( expected_elem . clone ( ) ) ;
495+ actual_index = actual . len ( ) ;
474496 break ;
475497 } ;
476- let Some ( index_offset) = input[ input_index..] . iter ( ) . position ( |next_input_elem| {
477- let mut next_input_elem = next_input_elem. clone ( ) ;
478- normalize_value_to_redactions ( & mut next_input_elem, next_pattern_elem, redactions) ;
479- next_input_elem == * * next_pattern_elem
498+ let Some ( index_offset) = actual[ actual_index..] . iter ( ) . position ( |next_actual_elem| {
499+ let mut next_actual_elem = next_actual_elem. clone ( ) ;
500+ normalize_value_to_redactions (
501+ & mut next_actual_elem,
502+ next_expected_elem,
503+ redactions,
504+ ) ;
505+ next_actual_elem == * * next_expected_elem
480506 } ) else {
481507 // Give up as we can't find where the elide ends
482508 break ;
483509 } ;
484- normalized. push ( pattern_elem . clone ( ) ) ;
485- input_index += index_offset;
510+ normalized. push ( expected_elem . clone ( ) ) ;
511+ actual_index += index_offset;
486512 } else {
487- let Some ( input_elem ) = input . get ( input_index ) else {
513+ let Some ( actual_elem ) = actual . get ( actual_index ) else {
488514 // Give up as we have no more content to check
489515 break ;
490516 } ;
491517
492- input_index += 1 ;
493- let mut normalized_elem = input_elem . clone ( ) ;
494- normalize_value_to_redactions ( & mut normalized_elem, pattern_elem , redactions) ;
518+ actual_index += 1 ;
519+ let mut normalized_elem = actual_elem . clone ( ) ;
520+ normalize_value_to_redactions ( & mut normalized_elem, expected_elem , redactions) ;
495521 normalized. push ( normalized_elem) ;
496522 }
497523 }
498524
499- normalized. extend ( input [ input_index ..] . iter ( ) . cloned ( ) ) ;
525+ normalized. extend ( actual [ actual_index ..] . iter ( ) . cloned ( ) ) ;
500526 normalized
501527}
502528
503- fn normalize_str_to_redactions ( input : & str , pattern : & str , redactions : & Redactions ) -> String {
504- if input == pattern {
505- return input . to_owned ( ) ;
529+ fn normalize_str_to_redactions ( actual : & str , expected : & str , redactions : & Redactions ) -> String {
530+ if actual == expected {
531+ return actual . to_owned ( ) ;
506532 }
507533
508534 let mut normalized: Vec < & str > = Vec :: new ( ) ;
509- let mut input_index = 0 ;
510- let input_lines : Vec < _ > = crate :: utils:: LinesWithTerminator :: new ( input ) . collect ( ) ;
511- let mut pattern_lines = crate :: utils:: LinesWithTerminator :: new ( pattern ) . peekable ( ) ;
512- while let Some ( pattern_line ) = pattern_lines . next ( ) {
513- if is_line_elide ( pattern_line ) {
514- let Some ( next_pattern_line ) = pattern_lines . peek ( ) else {
535+ let mut actual_index = 0 ;
536+ let actual_lines : Vec < _ > = crate :: utils:: LinesWithTerminator :: new ( actual ) . collect ( ) ;
537+ let mut expected_lines = crate :: utils:: LinesWithTerminator :: new ( expected ) . peekable ( ) ;
538+ while let Some ( expected_line ) = expected_lines . next ( ) {
539+ if is_line_elide ( expected_line ) {
540+ let Some ( next_expected_line ) = expected_lines . peek ( ) else {
515541 // Stop as elide consumes to end
516- normalized. push ( pattern_line ) ;
517- input_index = input_lines . len ( ) ;
542+ normalized. push ( expected_line ) ;
543+ actual_index = actual_lines . len ( ) ;
518544 break ;
519545 } ;
520546 let Some ( index_offset) =
521- input_lines [ input_index ..]
547+ actual_lines [ actual_index ..]
522548 . iter ( )
523- . position ( |next_input_line | {
524- line_matches ( next_input_line , next_pattern_line , redactions)
549+ . position ( |next_actual_line | {
550+ line_matches ( next_actual_line , next_expected_line , redactions)
525551 } )
526552 else {
527553 // Give up as we can't find where the elide ends
528554 break ;
529555 } ;
530- normalized. push ( pattern_line ) ;
531- input_index += index_offset;
556+ normalized. push ( expected_line ) ;
557+ actual_index += index_offset;
532558 } else {
533- let Some ( input_line ) = input_lines . get ( input_index ) else {
559+ let Some ( actual_line ) = actual_lines . get ( actual_index ) else {
534560 // Give up as we have no more content to check
535561 break ;
536562 } ;
537563
538- if line_matches ( input_line , pattern_line , redactions) {
539- input_index += 1 ;
540- normalized. push ( pattern_line ) ;
564+ if line_matches ( actual_line , expected_line , redactions) {
565+ actual_index += 1 ;
566+ normalized. push ( expected_line ) ;
541567 } else {
542568 // Skip this line and keep processing
543- input_index += 1 ;
544- normalized. push ( input_line ) ;
569+ actual_index += 1 ;
570+ normalized. push ( actual_line ) ;
545571 }
546572 }
547573 }
548574
549- normalized. extend ( input_lines [ input_index ..] . iter ( ) . copied ( ) ) ;
575+ normalized. extend ( actual_lines [ actual_index ..] . iter ( ) . copied ( ) ) ;
550576 normalized. join ( "" )
551577}
552578
553579fn is_line_elide ( line : & str ) -> bool {
554580 line == "...\n " || line == "..."
555581}
556582
557- fn line_matches ( mut input : & str , pattern : & str , redactions : & Redactions ) -> bool {
558- if input == pattern {
583+ fn line_matches ( mut actual : & str , expected : & str , redactions : & Redactions ) -> bool {
584+ if actual == expected {
559585 return true ;
560586 }
561587
562- let pattern = redactions. clear ( pattern ) ;
563- let mut sections = pattern . split ( "[..]" ) . peekable ( ) ;
588+ let expected = redactions. clear ( expected ) ;
589+ let mut sections = expected . split ( "[..]" ) . peekable ( ) ;
564590 while let Some ( section) = sections. next ( ) {
565- if let Some ( remainder) = input . strip_prefix ( section) {
591+ if let Some ( remainder) = actual . strip_prefix ( section) {
566592 if let Some ( next_section) = sections. peek ( ) {
567593 if next_section. is_empty ( ) {
568- input = "" ;
594+ actual = "" ;
569595 } else if let Some ( restart_index) = remainder. find ( next_section) {
570- input = & remainder[ restart_index..] ;
596+ actual = & remainder[ restart_index..] ;
571597 }
572598 } else {
573599 return remainder. is_empty ( ) ;
0 commit comments