diff --git a/modules/common/src/main/scala/docspell/common/IdRef.scala b/modules/common/src/main/scala/docspell/common/IdRef.scala index 8c32405c..918030e7 100644 --- a/modules/common/src/main/scala/docspell/common/IdRef.scala +++ b/modules/common/src/main/scala/docspell/common/IdRef.scala @@ -1,5 +1,7 @@ package docspell.common +import cats.Order + import io.circe._ import io.circe.generic.semiauto._ @@ -11,4 +13,7 @@ object IdRef { deriveEncoder[IdRef] implicit val jsonDecoder: Decoder[IdRef] = deriveDecoder[IdRef] + + implicit val order: Order[IdRef] = + Order.by(_.id) } diff --git a/modules/common/src/main/scala/docspell/common/Ident.scala b/modules/common/src/main/scala/docspell/common/Ident.scala index dcb8cf2d..95e58bc6 100644 --- a/modules/common/src/main/scala/docspell/common/Ident.scala +++ b/modules/common/src/main/scala/docspell/common/Ident.scala @@ -6,6 +6,7 @@ import java.util.UUID import cats.Eq import cats.effect.Sync import cats.implicits._ +import cats.Order import io.circe.{Decoder, Encoder} import scodec.bits.ByteVector @@ -66,4 +67,7 @@ object Ident { implicit val decodeIdent: Decoder[Ident] = Decoder.decodeString.emap(Ident.fromString) + implicit val order: Order[Ident] = + Order.by(_.id) + } diff --git a/modules/common/src/main/scala/docspell/common/MetaProposal.scala b/modules/common/src/main/scala/docspell/common/MetaProposal.scala index 62a9355f..36f4be1c 100644 --- a/modules/common/src/main/scala/docspell/common/MetaProposal.scala +++ b/modules/common/src/main/scala/docspell/common/MetaProposal.scala @@ -2,9 +2,9 @@ package docspell.common import java.time.LocalDate +import cats.Order import cats.data.NonEmptyList import cats.implicits._ -import cats.kernel.Order import docspell.common.MetaProposal.Candidate import docspell.common._ @@ -74,6 +74,9 @@ object MetaProposal { implicit val jsonDecoder: Decoder[Candidate] = deriveDecoder[Candidate] + implicit val order: Order[Candidate] = + Order.by(_.ref) + /** This deviates from standard order to sort None at last. */ val weightOrder: Order[Option[Double]] = new Order[Option[Double]] { diff --git a/modules/common/src/main/scala/docspell/common/MetaProposalList.scala b/modules/common/src/main/scala/docspell/common/MetaProposalList.scala index 04cedb30..33865484 100644 --- a/modules/common/src/main/scala/docspell/common/MetaProposalList.scala +++ b/modules/common/src/main/scala/docspell/common/MetaProposalList.scala @@ -52,7 +52,8 @@ case class MetaProposalList private (proposals: List[MetaProposal]) { (map, next) => map.get(next.proposalType) match { case Some(MetaProposal(mt, values)) => - val cand = NonEmptyList(values.head, next.values.toList ++ values.tail) + val cand = + NonEmptyList(values.head, next.values.toList ++ values.tail).distinct map.updated(next.proposalType, MetaProposal(mt, MetaProposal.flatten(cand))) case None => map.updated(next.proposalType, next) diff --git a/modules/common/src/test/scala/docspell/common/MetaProposalListTest.scala b/modules/common/src/test/scala/docspell/common/MetaProposalListTest.scala index 44a6cfc2..c35bafcc 100644 --- a/modules/common/src/test/scala/docspell/common/MetaProposalListTest.scala +++ b/modules/common/src/test/scala/docspell/common/MetaProposalListTest.scala @@ -99,4 +99,34 @@ object MetaProposalListTest extends SimpleTestSuite { ) ) } + + test("insert second, remove duplicates") { + val cand1 = Candidate(IdRef(Ident.unsafe("123"), "name"), Set.empty) + val cand2 = Candidate(IdRef(Ident.unsafe("456"), "name"), Set.empty) + val cand3 = Candidate(IdRef(Ident.unsafe("789"), "name"), Set.empty) + val cand5 = Candidate(IdRef(Ident.unsafe("def"), "name"), Set.empty) + + val mpl1 = MetaProposalList + .of( + MetaProposal(MetaProposalType.CorrOrg, NonEmptyList.of(cand1, cand2)), + MetaProposal(MetaProposalType.ConcPerson, NonEmptyList.of(cand3)) + ) + + val mpl2 = MetaProposalList + .of( + MetaProposal(MetaProposalType.CorrOrg, NonEmptyList.of(cand1)), + MetaProposal(MetaProposalType.ConcPerson, NonEmptyList.of(cand5)) + ) + + val result = mpl1.insertSecond(mpl2) + assertEquals( + result, + MetaProposalList( + List( + MetaProposal(MetaProposalType.CorrOrg, NonEmptyList.of(cand1, cand2)), + MetaProposal(MetaProposalType.ConcPerson, NonEmptyList.of(cand3, cand5)) + ) + ) + ) + } }