chwthewke / auto-diff
Showing 1 of 2 files from the diff.
Other files ignored by Codecov

@@ -3,6 +3,7 @@
 3 3 import cats.data.Ior 4 4 import cats.data.NonEmptyList 5 5 import cats.syntax.option._ 6 + import scala.annotation.tailrec 6 7 7 8 case class DiffMatch[A]( difference: Option[Difference.Unordered], matches: List[( A, A )] ) 8 9
@@ -32,31 +33,33 @@
 32 33 )( implicit D: Diff[A], H: Hint[A] ): ( List[A], List[A], List[( A, A )], List[Difference] ) = { 33 34 right.foldRight( ( left.toList, List.empty[A], List.empty[( A, A )], List.empty[Difference] ) ) { 34 35 case ( elem, ( remaining, unmatched, matches, mismatches ) ) => 35 - def remainingAfter( matched: A ): List[A] = remaining.filterNot( matched == _ ) 36 + def remainingAfter( matchedIx: Int ): List[A] = remaining.take( matchedIx ) ++ remaining.drop( matchedIx + 1 ) 36 37 37 38 def explainMismatch( a: A, d: Difference ): Difference = Difference.Tagged( s"at \${H.show( a )}", d ) 38 39 39 - def search( prevMis: Option[( A, Difference )], excessMis: Boolean )( 40 - cands: List[A] 41 - ): Either[Option[( A, Difference )], A] = cands match { 42 - case Nil => Left( prevMis.map { case ( a, d ) => ( a, explainMismatch( a, d ) ) } ) 43 - case cand :: more if H( cand, elem ) => 40 + @tailrec 41 + def search( prevMis: Option[( A, Int, Difference )], excessMis: Boolean )( 42 + cands: List[( A, Int )] 43 + ): Either[Option[( Int, Difference )], ( A, Int )] = cands match { 44 + case Nil => Left( prevMis.map { case ( a, ix, d ) => ( ix, explainMismatch( a, d ) ) } ) 45 + case ( cand, ix ) :: more if H( cand, elem ) => 44 46 D( cand, elem ) match { 45 - case None => Right( cand ) 47 + case None => Right( ( cand, ix ) ) 46 48 case mis @ Some( _ ) => 47 49 val ( p, e ) = 48 50 if (excessMis || prevMis.nonEmpty || H.isDefault) ( none, true ) 49 - else ( mis.map( cand -> _ ), false ) 51 + else ( mis.map( ( cand, ix, _ ) ), false ) 50 52 search( p, e )( more ) 51 53 } 52 54 case _ :: more => search( prevMis, excessMis )( more ) 53 55 } 54 56 55 - search( none, false )( remaining ) match { 56 - case Right( newMatch ) => ( remainingAfter( newMatch ), unmatched, ( newMatch, elem ) :: matches, mismatches ) 57 - case Left( None ) => ( remaining, elem :: unmatched, matches, mismatches ) 58 - case Left( Some( ( mismatched, mismatch ) ) ) => 59 - ( remainingAfter( mismatched ), unmatched, matches, mismatch :: mismatches ) 57 + search( none, excessMis = false )( remaining.zipWithIndex ) match { 58 + case Right( ( newMatch, ix ) ) => 59 + ( remainingAfter( ix ), unmatched, ( newMatch, elem ) :: matches, mismatches ) 60 + case Left( None ) => ( remaining, elem :: unmatched, matches, mismatches ) 61 + case Left( Some( ( ix, mismatch ) ) ) => 62 + ( remainingAfter( ix ), unmatched, matches, mismatch :: mismatches ) 60 63 } 61 64 62 65 }
211.2
default=
TRAVIS_OS_NAME=linux
201.2
default=
TRAVIS_OS_NAME=linux
200.2
default=
TRAVIS_OS_NAME=linux
203.2
default=
TRAVIS_OS_NAME=linux
202.2
default=
TRAVIS_OS_NAME=linux
205.2
default=
TRAVIS_OS_NAME=linux
204.2
default=
TRAVIS_OS_NAME=linux
207.2
default=
TRAVIS_OS_NAME=linux
206.2
default=
TRAVIS_OS_NAME=linux
209.2
default=
TRAVIS_OS_NAME=linux
208.2
default=
TRAVIS_OS_NAME=linux