From fdc6dbf2945538f601d96dbc73e40fa3c75dc39c Mon Sep 17 00:00:00 2001 From: Jonas Chapuis Date: Mon, 27 Nov 2023 08:48:06 +0100 Subject: [PATCH] Scala 3 support --- akka-runtime/src/main/protobuf/command.proto | 5 ++ .../runtime/akka/EntityPassivator.scala | 14 ++--- .../runtime/akka/ShardingCommandSender.scala | 6 +- .../runtime/akka/deploy/AkkaCluster.scala | 12 ++-- .../runtime/akka/deploy/AkkaDeployer.scala | 10 ++-- .../akka/deploy/AkkaDurableDeployer.scala | 8 +-- .../DurableShardedRepositoryDeployer.scala | 16 ++--- ...ventSourcedShardedRepositoryDeployer.scala | 12 ++-- .../internal/ShardedRepositoryDeployer.scala | 4 +- .../akka/protobuf/ScalaPbSerializer.scala | 10 ++-- .../akka/serializer/CommandSerializer.scala | 2 +- akka-runtime/src/test/protobuf/dummy.proto | 6 ++ build.sbt | 59 +++++++++++++------ .../scala/endless/circe/CirceDecoder.scala | 2 +- .../endless/circe/CirceIncomingCommand.scala | 2 +- .../circe/CirceCommandProtocolSuite.scala | 2 +- .../endless/core/data/EventsFolder.scala | 3 +- .../scala/endless/core/entity/Effector.scala | 6 +- .../core/entity/StateReaderHelpers.scala | 8 +-- .../endless/core/event/EventApplier.scala | 2 - .../core/interpret/EntityRunFunctions.scala | 6 +- .../endless/core/interpret/EntityT.scala | 12 ++-- .../core/interpret/EntityTLiftInstance.scala | 12 ++-- .../endless/core/protocol/CommandSender.scala | 2 +- .../endless/core/entity/EffectorSuite.scala | 4 +- .../core/entity/StateReaderHelpersSuite.scala | 18 +++--- .../core/interpret/DurableEntityTSuite.scala | 10 ++-- .../endless/core/interpret/EntityTSuite.scala | 39 ++++++------ example/src/main/protobuf/package.proto | 9 +++ .../example/adapter/BookingEventAdapter.scala | 7 ++- .../endless/example/app/HttpServer.scala | 14 ++--- .../endless/example/app/akka/AkkaApp.scala | 14 ++--- .../scala/endless/example/app/akka/Main.scala | 2 +- .../example/app/impl/Availabilities.scala | 8 +-- .../endless/example/app/impl/Bookings.scala | 2 +- .../endless/example/app/impl/Vehicles.scala | 2 +- .../endless/example/app/pekko/PekkoApp.scala | 14 ++--- .../scala/endless/example/data/Booking.scala | 7 ++- .../endless/example/data/BookingEvent.scala | 6 +- .../scala/endless/example/data/LatLon.scala | 2 +- .../scala/endless/example/data/Speed.scala | 4 +- .../scala/endless/example/data/Vehicle.scala | 3 +- .../endless/example/logic/BookingEntity.scala | 14 ++--- .../example/logic/BookingEventApplier.scala | 4 +- .../example/logic/BookingSideEffect.scala | 14 ++--- .../endless/example/logic/VehicleEntity.scala | 8 +-- .../example/logic/VehicleSideEffect.scala | 6 +- .../protocol/BookingCommandProtocol.scala | 21 +++---- .../protocol/VehicleCommandProtocol.scala | 2 +- .../endless/example/AkkaExampleAppSuite.scala | 2 +- .../endless/example/ExampleAppSuite.scala | 14 ++--- .../example/PekkoExampleAppSuite.scala | 2 +- .../example/logic/BookingEntitySuite.scala | 24 ++++---- .../logic/BookingEventApplierSuite.scala | 25 ++++---- .../logic/BookingSideEffectSuite.scala | 24 ++++---- .../endless/example/logic/Generators.scala | 2 +- .../example/logic/VehicleEntitySuite.scala | 8 +-- .../logic/VehicleSideEffectSuite.scala | 2 +- pekko-runtime/src/main/protobuf/command.proto | 5 ++ .../runtime/pekko/EntityPassivator.scala | 14 ++--- .../runtime/pekko/ShardingCommandSender.scala | 6 +- .../runtime/pekko/deploy/PekkoCluster.scala | 12 ++-- .../runtime/pekko/deploy/PekkoDeployer.scala | 8 +-- .../pekko/deploy/PekkoDurableDeployer.scala | 8 +-- .../DurableShardedEntityDeployer.scala | 16 ++--- .../EventSourcedShardedEntityDeployer.scala | 12 ++-- .../internal/ShardedRepositoryDeployer.scala | 4 +- .../pekko/protobuf/ScalaPbSerializer.scala | 10 ++-- .../pekko/serializer/CommandSerializer.scala | 2 +- pekko-runtime/src/test/protobuf/dummy.proto | 5 ++ project/Dependencies.scala | 4 +- protobuf/src/test/protobuf/dummy.proto | 5 ++ .../scodec/ScodecCommandProtocolSuite.scala | 8 +-- 73 files changed, 368 insertions(+), 309 deletions(-) create mode 100644 example/src/main/protobuf/package.proto diff --git a/akka-runtime/src/main/protobuf/command.proto b/akka-runtime/src/main/protobuf/command.proto index 27a1cde9..7da10e9d 100644 --- a/akka-runtime/src/main/protobuf/command.proto +++ b/akka-runtime/src/main/protobuf/command.proto @@ -1,4 +1,9 @@ syntax = "proto2"; +import "scalapb/scalapb.proto"; + +option (scalapb.options) = { + scala3_sources: true +}; package endless.runtime.akka.serializer.proto; option optimize_for = SPEED; diff --git a/akka-runtime/src/main/scala/endless/runtime/akka/EntityPassivator.scala b/akka-runtime/src/main/scala/endless/runtime/akka/EntityPassivator.scala index e96338f8..7e45ddec 100644 --- a/akka-runtime/src/main/scala/endless/runtime/akka/EntityPassivator.scala +++ b/akka-runtime/src/main/scala/endless/runtime/akka/EntityPassivator.scala @@ -5,17 +5,17 @@ import akka.actor.typed.scaladsl.ActorContext import akka.cluster.sharding.typed.scaladsl.{ClusterSharding, EntityContext} import cats.Applicative import cats.effect.kernel.{Ref, Sync} -import cats.syntax.eq._ -import cats.syntax.flatMap._ -import cats.syntax.functor._ +import cats.syntax.eq.* +import cats.syntax.flatMap.* +import cats.syntax.functor.* import endless.core.entity.Effector.PassivationState import scala.concurrent.duration.{Duration, FiniteDuration} private[akka] class EntityPassivator[F[_]: Sync](upcomingPassivation: Ref[F, Option[Cancellable]])( implicit - entityContext: EntityContext[_], - actorContext: ActorContext[_] + entityContext: EntityContext[?], + actorContext: ActorContext[?] ) { private lazy val passivateMessage = ClusterSharding.Passivate(actorContext.self) private lazy val passivate = Sync[F].delay(entityContext.shard.tell(passivateMessage)) @@ -44,8 +44,8 @@ private[akka] class EntityPassivator[F[_]: Sync](upcomingPassivation: Ref[F, Opt object EntityPassivator { def apply[F[_]: Sync](implicit - entityContext: EntityContext[_], - actorContext: ActorContext[_] + entityContext: EntityContext[?], + actorContext: ActorContext[?] ): F[EntityPassivator[F]] = Ref.of[F, Option[Cancellable]](Option.empty[Cancellable]).map(new EntityPassivator(_)) } diff --git a/akka-runtime/src/main/scala/endless/runtime/akka/ShardingCommandSender.scala b/akka-runtime/src/main/scala/endless/runtime/akka/ShardingCommandSender.scala index 6f6434c5..1a37e944 100644 --- a/akka-runtime/src/main/scala/endless/runtime/akka/ShardingCommandSender.scala +++ b/akka-runtime/src/main/scala/endless/runtime/akka/ShardingCommandSender.scala @@ -3,9 +3,9 @@ package endless.runtime.akka import akka.cluster.sharding.typed.scaladsl.{ClusterSharding, EntityTypeKey} import akka.util.Timeout import cats.effect.kernel.Async -import cats.syntax.applicative._ -import cats.syntax.flatMap._ -import cats.syntax.show._ +import cats.syntax.applicative.* +import cats.syntax.flatMap.* +import cats.syntax.show.* import cats.~> import endless.core.entity.EntityNameProvider import endless.core.protocol.{CommandSender, EntityIDEncoder, OutgoingCommand} diff --git a/akka-runtime/src/main/scala/endless/runtime/akka/deploy/AkkaCluster.scala b/akka-runtime/src/main/scala/endless/runtime/akka/deploy/AkkaCluster.scala index a64be91d..c6b0b503 100644 --- a/akka-runtime/src/main/scala/endless/runtime/akka/deploy/AkkaCluster.scala +++ b/akka-runtime/src/main/scala/endless/runtime/akka/deploy/AkkaCluster.scala @@ -5,12 +5,12 @@ import akka.actor.CoordinatedShutdown import akka.actor.typed.ActorSystem import akka.cluster.{Cluster, MemberStatus} import akka.cluster.sharding.typed.scaladsl.ClusterSharding -import cats.effect.kernel.implicits._ +import cats.effect.kernel.implicits.* import cats.effect.kernel.{Async, Deferred, Resource, Sync} import cats.effect.std.Dispatcher import cats.implicits.catsSyntaxApplicativeError -import cats.syntax.flatMap._ -import cats.syntax.functor._ +import cats.syntax.flatMap.* +import cats.syntax.functor.* import org.typelevel.log4cats.Logger import scala.concurrent.TimeoutException @@ -27,7 +27,7 @@ import scala.concurrent.duration.{Duration, DurationInt} * effects dispatcher tied to the cluster resource scope */ final case class AkkaCluster[F[_]: Async]( - system: ActorSystem[_], + system: ActorSystem[?], dispatcher: Dispatcher[F], cluster: Cluster, sharding: ClusterSharding @@ -65,7 +65,7 @@ object AkkaCluster { * seconds by default). */ def managedResource[F[_]: Async: Logger]( - createActorSystem: => ActorSystem[_], + createActorSystem: => ActorSystem[?], catsEffectReleaseTimeout: Duration = 5.seconds, akkaReleaseTimeout: Duration = 5.seconds ): Resource[F, AkkaCluster[F]] = @@ -115,7 +115,7 @@ object AkkaCluster { ) private def createCluster[F[_]: Async: Logger]( - createActorSystem: => ActorSystem[_], + createActorSystem: => ActorSystem[?], dispatcher: Dispatcher[F] ) = for { system <- Sync[F].delay(createActorSystem) diff --git a/akka-runtime/src/main/scala/endless/runtime/akka/deploy/AkkaDeployer.scala b/akka-runtime/src/main/scala/endless/runtime/akka/deploy/AkkaDeployer.scala index 6032a078..6b9a8d50 100644 --- a/akka-runtime/src/main/scala/endless/runtime/akka/deploy/AkkaDeployer.scala +++ b/akka-runtime/src/main/scala/endless/runtime/akka/deploy/AkkaDeployer.scala @@ -6,12 +6,12 @@ import akka.cluster.sharding.typed.scaladsl.{ClusterSharding, EntityContext} import akka.persistence.typed.scaladsl.EventSourcedBehavior import akka.util.Timeout import cats.effect.kernel.{Async, Resource} -import endless.core.entity._ +import endless.core.entity.* import endless.core.event.EventApplier -import endless.core.interpret._ +import endless.core.interpret.* import endless.core.protocol.{CommandProtocol, CommandSender, EntityIDCodec} -import endless.runtime.akka.data._ -import AkkaDeployer._ +import endless.runtime.akka.data.* +import AkkaDeployer.* import endless.runtime.akka.deploy.internal.EventSourcedShardedRepositoryDeployer import org.typelevel.log4cats.Logger import endless.core.entity.Deployer @@ -33,7 +33,7 @@ trait AkkaDeployer extends Deployer { eventApplier: EventApplier[S, E], parameters: AkkaDeploymentParameters[F, S, E] ): Resource[F, DeployedAkkaRepository[F, RepositoryAlg]] = { - import parameters._ + import parameters.* implicit val sharding: ClusterSharding = akkaCluster.sharding implicit val sender: CommandSender[F, ID] = ShardingCommandSender[F, ID] for { diff --git a/akka-runtime/src/main/scala/endless/runtime/akka/deploy/AkkaDurableDeployer.scala b/akka-runtime/src/main/scala/endless/runtime/akka/deploy/AkkaDurableDeployer.scala index b71dec03..3254e30e 100644 --- a/akka-runtime/src/main/scala/endless/runtime/akka/deploy/AkkaDurableDeployer.scala +++ b/akka-runtime/src/main/scala/endless/runtime/akka/deploy/AkkaDurableDeployer.scala @@ -6,11 +6,11 @@ import akka.cluster.sharding.typed.scaladsl.{ClusterSharding, EntityContext} import akka.persistence.typed.state.scaladsl.DurableStateBehavior import akka.util.Timeout import cats.effect.kernel.{Async, Resource} -import endless.core.entity._ -import endless.core.interpret._ +import endless.core.entity.* +import endless.core.interpret.* import endless.core.protocol.{CommandProtocol, CommandSender, EntityIDCodec} import endless.runtime.akka.ShardingCommandSender -import endless.runtime.akka.data._ +import endless.runtime.akka.data.* import endless.runtime.akka.deploy.AkkaDurableDeployer.{ AkkaDurableDeploymentParameters, DeployedAkkaDurableRepository @@ -34,7 +34,7 @@ trait AkkaDurableDeployer extends DurableDeployer { commandProtocol: CommandProtocol[ID, Alg], parameters: AkkaDurableDeploymentParameters[F, S] ): Resource[F, DeployedAkkaDurableRepository[F, RepositoryAlg]] = { - import parameters._ + import parameters.* implicit val sharding: ClusterSharding = akkaCluster.sharding implicit val sender: CommandSender[F, ID] = ShardingCommandSender[F, ID] for { diff --git a/akka-runtime/src/main/scala/endless/runtime/akka/deploy/internal/DurableShardedRepositoryDeployer.scala b/akka-runtime/src/main/scala/endless/runtime/akka/deploy/internal/DurableShardedRepositoryDeployer.scala index 7b463703..c8fc9867 100644 --- a/akka-runtime/src/main/scala/endless/runtime/akka/deploy/internal/DurableShardedRepositoryDeployer.scala +++ b/akka-runtime/src/main/scala/endless/runtime/akka/deploy/internal/DurableShardedRepositoryDeployer.scala @@ -8,16 +8,16 @@ import akka.persistence.typed.state.scaladsl.{DurableStateBehavior, Effect} import akka.persistence.typed.state.{RecoveryCompleted, RecoveryFailed} import cats.effect.kernel.Async import cats.effect.std.Dispatcher -import cats.syntax.applicative._ -import cats.syntax.flatMap._ -import cats.syntax.functor._ -import cats.syntax.show._ -import endless.core.entity._ +import cats.syntax.applicative.* +import cats.syntax.flatMap.* +import cats.syntax.functor.* +import cats.syntax.show.* +import endless.core.entity.* import endless.core.interpret.DurableEntityT.{DurableEntityT, State} -import endless.core.interpret._ +import endless.core.interpret.* import endless.core.protocol.{CommandProtocol, CommandSender, EntityIDCodec} import endless.runtime.akka.EntityPassivator -import endless.runtime.akka.data._ +import endless.runtime.akka.data.* import org.typelevel.log4cats.Logger private[deploy] class DurableShardedRepositoryDeployer[F[ @@ -110,7 +110,7 @@ private[deploy] class DurableShardedRepositoryDeployer[F[ // run the effector asynchronously, as it can describe long-running processes dispatcher.unsafeRunAndForget(handleSideEffect(state)) ) - .thenReply(command.replyTo) { _: Option[S] => + .thenReply(command.replyTo) { (_: Option[S]) => Reply(incomingCommand.replyEncoder.encode(reply)) } .pure[F] diff --git a/akka-runtime/src/main/scala/endless/runtime/akka/deploy/internal/EventSourcedShardedRepositoryDeployer.scala b/akka-runtime/src/main/scala/endless/runtime/akka/deploy/internal/EventSourcedShardedRepositoryDeployer.scala index cc96a2f5..8f20a9cd 100644 --- a/akka-runtime/src/main/scala/endless/runtime/akka/deploy/internal/EventSourcedShardedRepositoryDeployer.scala +++ b/akka-runtime/src/main/scala/endless/runtime/akka/deploy/internal/EventSourcedShardedRepositoryDeployer.scala @@ -7,17 +7,17 @@ import akka.persistence.typed.scaladsl.{Effect, EventSourcedBehavior} import akka.persistence.typed.{PersistenceId, RecoveryCompleted, RecoveryFailed} import cats.effect.kernel.Async import cats.effect.std.Dispatcher -import cats.syntax.applicative._ -import cats.syntax.flatMap._ -import cats.syntax.functor._ -import cats.syntax.show._ +import cats.syntax.applicative.* +import cats.syntax.flatMap.* +import cats.syntax.functor.* +import cats.syntax.show.* import endless.core.entity.{Effector, EntityNameProvider, Sharding, SideEffect} import endless.core.event.EventApplier import endless.core.interpret.{EntityT, SideEffectInterpreter} import endless.core.protocol.{CommandProtocol, CommandSender, EntityIDCodec} import endless.runtime.akka.EntityPassivator import endless.runtime.akka.data.{Command, Reply} -import endless.runtime.akka.deploy.internal.EventSourcedShardedRepositoryDeployer._ +import endless.runtime.akka.deploy.internal.EventSourcedShardedRepositoryDeployer.* import org.typelevel.log4cats.Logger private[deploy] class EventSourcedShardedRepositoryDeployer[F[ @@ -118,7 +118,7 @@ private[deploy] class EventSourcedShardedRepositoryDeployer[F[ ]) => // run the effector asynchronously, as it can describe long-running processes dispatcher.unsafeRunAndForget(handleSideEffect(state)) ) - .thenReply(command.replyTo) { _: Option[S] => + .thenReply(command.replyTo) { (_: Option[S]) => Reply(incomingCommand.replyEncoder.encode(reply)) } .pure[F] diff --git a/akka-runtime/src/main/scala/endless/runtime/akka/deploy/internal/ShardedRepositoryDeployer.scala b/akka-runtime/src/main/scala/endless/runtime/akka/deploy/internal/ShardedRepositoryDeployer.scala index 9d291cd8..41789d0c 100644 --- a/akka-runtime/src/main/scala/endless/runtime/akka/deploy/internal/ShardedRepositoryDeployer.scala +++ b/akka-runtime/src/main/scala/endless/runtime/akka/deploy/internal/ShardedRepositoryDeployer.scala @@ -7,11 +7,11 @@ import akka.cluster.sharding.typed.scaladsl.{ClusterSharding, EntityContext, Ent import akka.util.Timeout import cats.effect.kernel.{Async, Resource} import cats.effect.std.Dispatcher -import endless.core.entity._ +import endless.core.entity.* import endless.core.interpret.RepositoryInterpreter import endless.core.protocol.{CommandProtocol, CommandSender, EntityIDEncoder} import endless.runtime.akka.ShardingCommandSender -import endless.runtime.akka.data._ +import endless.runtime.akka.data.* import endless.runtime.akka.deploy.AkkaCluster import org.typelevel.log4cats.Logger diff --git a/akka-runtime/src/main/scala/endless/runtime/akka/protobuf/ScalaPbSerializer.scala b/akka-runtime/src/main/scala/endless/runtime/akka/protobuf/ScalaPbSerializer.scala index 0a4804df..b223df22 100644 --- a/akka-runtime/src/main/scala/endless/runtime/akka/protobuf/ScalaPbSerializer.scala +++ b/akka-runtime/src/main/scala/endless/runtime/akka/protobuf/ScalaPbSerializer.scala @@ -19,7 +19,7 @@ import java.util.concurrent.atomic.AtomicReference ) class ScalaPbSerializer(val system: ExtendedActorSystem) extends BaseSerializer { private val classToCompanionMapRef = - new AtomicReference[Map[Class[_], GeneratedMessageCompanion[_]]](Map.empty) + new AtomicReference[Map[Class[?], GeneratedMessageCompanion[?]]](Map.empty) override def toBinary(o: AnyRef): Array[Byte] = o match { case e: scalapb.GeneratedMessage => e.toByteArray @@ -28,14 +28,14 @@ class ScalaPbSerializer(val system: ExtendedActorSystem) extends BaseSerializer override def includeManifest: Boolean = true - override def fromBinary(bytes: Array[Byte], manifest: Option[Class[_]]): AnyRef = + override def fromBinary(bytes: Array[Byte], manifest: Option[Class[?]]): AnyRef = manifest match { case Some(clazz) => // noinspection ScalaStyle @scala.annotation.tailrec def messageCompanion( - companion: GeneratedMessageCompanion[_] = null - ): GeneratedMessageCompanion[_] = { + companion: GeneratedMessageCompanion[?] = null + ): GeneratedMessageCompanion[?] = { val classToCompanion = classToCompanionMapRef.get() classToCompanion.get(clazz) match { case Some(cachedCompanion) => cachedCompanion @@ -46,7 +46,7 @@ class ScalaPbSerializer(val system: ExtendedActorSystem) extends BaseSerializer .forName(clazz.getName + "$", true, clazz.getClassLoader) .getField("MODULE$") .get(()) - .asInstanceOf[GeneratedMessageCompanion[_]] + .asInstanceOf[GeneratedMessageCompanion[?]] else companion if ( classToCompanionMapRef.compareAndSet( diff --git a/akka-runtime/src/main/scala/endless/runtime/akka/serializer/CommandSerializer.scala b/akka-runtime/src/main/scala/endless/runtime/akka/serializer/CommandSerializer.scala index b920a2a0..401e912f 100644 --- a/akka-runtime/src/main/scala/endless/runtime/akka/serializer/CommandSerializer.scala +++ b/akka-runtime/src/main/scala/endless/runtime/akka/serializer/CommandSerializer.scala @@ -3,7 +3,7 @@ package endless.runtime.akka.serializer import akka.actor.typed.ActorRefResolver import akka.actor.typed.scaladsl.adapter.ClassicActorSystemOps import akka.serialization.{BaseSerializer, SerializerWithStringManifest} -import cats.syntax.show._ +import cats.syntax.show.* import com.google.protobuf.ByteString import endless.runtime.akka.data.Command import endless.runtime.akka.serializer.CommandSerializer.ManifestKey diff --git a/akka-runtime/src/test/protobuf/dummy.proto b/akka-runtime/src/test/protobuf/dummy.proto index 22458fe5..4b0c1561 100644 --- a/akka-runtime/src/test/protobuf/dummy.proto +++ b/akka-runtime/src/test/protobuf/dummy.proto @@ -1,5 +1,11 @@ syntax = "proto3"; +import "scalapb/scalapb.proto"; + +option (scalapb.options) = { + scala3_sources: true +}; + package endless.protobuf.test.proto; message DummyCommand { diff --git a/build.sbt b/build.sbt index d7696135..dcb06d8e 100644 --- a/build.sbt +++ b/build.sbt @@ -1,13 +1,32 @@ -import Dependencies._ +import Dependencies.* import sbtversionpolicy.Compatibility.None +val scala213 = "2.13.12" +val scala3 = "3.3.1" + val commonSettings = Seq( - scalacOptions ++= Seq("-Xfatal-warnings", "-Xlint:unused"), - addCompilerPlugin("org.typelevel" % "kind-projector" % "0.13.2" cross CrossVersion.full), wartremoverExcluded += sourceManaged.value, - Compile / compile / wartremoverErrors ++= Warts - .allBut(Wart.Any, Wart.Nothing, Wart.ImplicitParameter, Wart.Throw, Wart.DefaultArguments), - coverageExcludedPackages := ";endless.test.*" + Compile / compile / wartremoverErrors ++= Warts.allBut( + Wart.Any, + Wart.Nothing, + Wart.ImplicitParameter, + Wart.Throw, + Wart.DefaultArguments + ), + scalaVersion := scala213, + crossScalaVersions := Seq(scala213, scala3), + libraryDependencies ++= (CrossVersion.partialVersion(scalaVersion.value) match { + case Some((2, _)) => + Seq(compilerPlugin("org.typelevel" % "kind-projector" % "0.13.2" cross CrossVersion.full)) + case _ => Nil + }), + Compile / scalacOptions ++= Seq("-Xfatal-warnings"), + Compile / scalacOptions ++= (CrossVersion.partialVersion(scalaVersion.value) match { + case Some((3, _)) => Seq("-Ykind-projector:underscores") + case Some((2, _)) => + Seq("-Xsource:3", "-P:kind-projector:underscore-placeholders", "-Xlint:unused") + case _ => Nil + }) ) inThisBuild( @@ -27,19 +46,19 @@ inThisBuild( sonatypeProjectHosting := Some( xerial.sbt.Sonatype.GitHubHosting("endless4s", "endless", "me@jonaschapuis.com") ), - scalaVersion := "2.13.12", Global / onChangedBuildSource := ReloadOnSourceChanges, PB.protocVersion := "3.17.3", // works on Apple Silicon, versionPolicyIntention := Compatibility.None, versionScheme := Some("early-semver"), versionPolicyIgnoredInternalDependencyVersions := Some( "^\\d+\\.\\d+\\.\\d+\\+\\d+".r - ) // Support for versions generated by sbt-dynver + ), // Support for versions generated by sbt-dynver + coverageExcludedPackages := ";endless.test.*" ) ) lazy val core = (project in file("core")) - .settings(commonSettings: _*) + .settings(commonSettings *) .settings( libraryDependencies ++= cats ++ catsEffectKernel ++ log4cats ++ (catsLaws ++ catsEffectLaws ++ catsEffect ++ catsTestkit ++ catsEffectTestKit ++ mUnit ++ catsEffectMUnit ++ scalacheckEffect ++ kittens) @@ -48,10 +67,10 @@ lazy val core = (project in file("core")) .settings(name := "endless-core") lazy val akkaRuntime = (project in file("akka-runtime")) + .settings(commonSettings *) .dependsOn(core) - .settings(commonSettings: _*) .settings( - libraryDependencies ++= catsEffectStd ++ akkaProvided ++ log4cats ++ (mUnit :+ akkaTypedTestkit % akkaVersion) + libraryDependencies ++= catsEffectStd ++ akkaProvided ++ log4cats ++ scalapbCustomizations ++ (mUnit :+ akkaTypedTestkit % akkaVersion) .map(_ % Test) ) .settings( @@ -66,10 +85,10 @@ lazy val akkaRuntime = (project in file("akka-runtime")) .settings(name := "endless-runtime-akka") lazy val pekkoRuntime = (project in file("pekko-runtime")) + .settings(commonSettings *) .dependsOn(core) - .settings(commonSettings: _*) .settings( - libraryDependencies ++= catsEffectStd ++ pekkoProvided ++ log4cats ++ (mUnit :+ pekkoTypedTestkit % pekkoVersion) + libraryDependencies ++= catsEffectStd ++ pekkoProvided ++ log4cats ++ scalapbCustomizations ++ (mUnit :+ pekkoTypedTestkit % pekkoVersion) .map(_ % Test) ) .settings( @@ -83,24 +102,25 @@ lazy val pekkoRuntime = (project in file("pekko-runtime")) .settings(name := "endless-runtime-pekko") lazy val circeHelpers = (project in file("circe")) + .settings(commonSettings *) .dependsOn(core) - .settings(commonSettings: _*) .settings( libraryDependencies ++= circe ++ mUnit.map(_ % Test) ) .settings(name := "endless-circe-helpers") lazy val scodecHelpers = (project in file("scodec")) + .settings(commonSettings *) + .settings(scalaVersion := scala3, crossScalaVersions := Nil) // only scala3 for scodec .dependsOn(core) - .settings(commonSettings: _*) .settings(libraryDependencies ++= scodecCore ++ mUnit.map(_ % Test)) .settings(name := "endless-scodec-helpers") lazy val protobufHelpers = (project in file("protobuf")) + .settings(commonSettings *) .dependsOn(core) - .settings(commonSettings: _*) .settings( - libraryDependencies ++= mUnit.map(_ % Test) + libraryDependencies ++= scalapbCustomizations ++ mUnit.map(_ % Test) ) .settings(name := "endless-protobuf-helpers") .settings( @@ -113,8 +133,8 @@ lazy val protobufHelpers = (project in file("protobuf")) ) lazy val example = (project in file("example")) + .settings(commonSettings *) .dependsOn(core, akkaRuntime, pekkoRuntime, circeHelpers, protobufHelpers) - .settings(commonSettings: _*) .settings( libraryDependencies ++= catsEffect ++ http4s ++ blaze ++ akka ++ pekko ++ scalapbCustomizations ++ akkaTest ++ pekkoTest ++ logback ++ log4catsSlf4j ++ (mUnit ++ catsEffectMUnit ++ scalacheckEffect ++ log4catsTesting) .map(_ % Test) @@ -199,7 +219,8 @@ lazy val root = project .in(file(".")) .aggregate(core, akkaRuntime, pekkoRuntime, circeHelpers, scodecHelpers, protobufHelpers, example) .dependsOn(example) - .settings(commonSettings: _*) + .settings(commonSettings *) + .settings(crossScalaVersions := Nil) .settings(publish / skip := true) .settings(name := "endless") diff --git a/circe/src/main/scala/endless/circe/CirceDecoder.scala b/circe/src/main/scala/endless/circe/CirceDecoder.scala index 821df831..cc618ec1 100644 --- a/circe/src/main/scala/endless/circe/CirceDecoder.scala +++ b/circe/src/main/scala/endless/circe/CirceDecoder.scala @@ -1,6 +1,6 @@ package endless.circe -import cats.syntax.either._ +import cats.syntax.either.* import endless.circe.CirceDecoder.{DecodingException, ParsingException} import endless.core.protocol.Decoder import io.circe.parser.parse diff --git a/circe/src/main/scala/endless/circe/CirceIncomingCommand.scala b/circe/src/main/scala/endless/circe/CirceIncomingCommand.scala index 1733a50b..f6402c41 100644 --- a/circe/src/main/scala/endless/circe/CirceIncomingCommand.scala +++ b/circe/src/main/scala/endless/circe/CirceIncomingCommand.scala @@ -1,6 +1,6 @@ package endless.circe -import endless.circe.CirceEncoder._ +import endless.circe.CirceEncoder.* import endless.core.protocol.IncomingCommand import io.circe.Encoder diff --git a/circe/src/test/scala/endless/circe/CirceCommandProtocolSuite.scala b/circe/src/test/scala/endless/circe/CirceCommandProtocolSuite.scala index c2b6514c..0f227990 100644 --- a/circe/src/test/scala/endless/circe/CirceCommandProtocolSuite.scala +++ b/circe/src/test/scala/endless/circe/CirceCommandProtocolSuite.scala @@ -1,7 +1,7 @@ package endless.circe import cats.Id import endless.core.protocol.{CommandSender, Decoder, IncomingCommand} -import io.circe.generic.auto._ +import io.circe.generic.auto.* import org.scalacheck.Prop.forAll class CirceCommandProtocolSuite extends munit.ScalaCheckSuite { diff --git a/core/src/main/scala/endless/core/data/EventsFolder.scala b/core/src/main/scala/endless/core/data/EventsFolder.scala index a0ffc4cf..6dc3d003 100644 --- a/core/src/main/scala/endless/core/data/EventsFolder.scala +++ b/core/src/main/scala/endless/core/data/EventsFolder.scala @@ -1,7 +1,7 @@ package endless.core.data import cats.Foldable -import cats.syntax.foldable._ +import cats.syntax.foldable.* import endless.\/ import endless.core.event.EventApplier @@ -16,7 +16,6 @@ import endless.core.event.EventApplier * event */ final case class EventsFolder[S, E](state: Option[S], applier: EventApplier[S, E]) { - @SuppressWarnings(Array("org.wartremover.warts.OptionPartial")) def applyOnFoldable[G[_]: Foldable](foldable: G[E]): String \/ Option[S] = foldable.foldM(state)(applier.apply) } diff --git a/core/src/main/scala/endless/core/entity/Effector.scala b/core/src/main/scala/endless/core/entity/Effector.scala index 3a82ab78..5c5da3dd 100644 --- a/core/src/main/scala/endless/core/entity/Effector.scala +++ b/core/src/main/scala/endless/core/entity/Effector.scala @@ -1,8 +1,8 @@ package endless.core.entity import cats.effect.kernel.{Concurrent, Ref} -import cats.syntax.applicative._ -import cats.syntax.flatMap._ -import cats.syntax.functor._ +import cats.syntax.applicative.* +import cats.syntax.flatMap.* +import cats.syntax.functor.* import cats.{Applicative, Monad} import scala.concurrent.duration.FiniteDuration diff --git a/core/src/main/scala/endless/core/entity/StateReaderHelpers.scala b/core/src/main/scala/endless/core/entity/StateReaderHelpers.scala index 8d60986b..620f9cfe 100644 --- a/core/src/main/scala/endless/core/entity/StateReaderHelpers.scala +++ b/core/src/main/scala/endless/core/entity/StateReaderHelpers.scala @@ -2,10 +2,10 @@ package endless.core.entity import cats.Monad import cats.data.EitherT -import cats.syntax.applicative._ -import cats.syntax.either._ -import cats.syntax.flatMap._ -import cats.syntax.functor._ +import cats.syntax.applicative.* +import cats.syntax.either.* +import cats.syntax.flatMap.* +import cats.syntax.functor.* import endless.\/ /** Set of convenience functions augmenting `StateReader` (that assume a `Monad` instance exists for diff --git a/core/src/main/scala/endless/core/event/EventApplier.scala b/core/src/main/scala/endless/core/event/EventApplier.scala index 7c993969..843ecc1f 100644 --- a/core/src/main/scala/endless/core/event/EventApplier.scala +++ b/core/src/main/scala/endless/core/event/EventApplier.scala @@ -5,8 +5,6 @@ import endless.\/ /** Function that defines transition of the state given an event (or invalid event for the given * state). * - * @note - * returning `None` allows ignoring irrelevant events before entity is created * @tparam S * state * @tparam E diff --git a/core/src/main/scala/endless/core/interpret/EntityRunFunctions.scala b/core/src/main/scala/endless/core/interpret/EntityRunFunctions.scala index da4ec1cc..3f614e95 100644 --- a/core/src/main/scala/endless/core/interpret/EntityRunFunctions.scala +++ b/core/src/main/scala/endless/core/interpret/EntityRunFunctions.scala @@ -1,9 +1,9 @@ package endless.core.interpret -import cats.conversions.all._ +import cats.conversions.all.* import cats.data.{Chain, NonEmptyChain} -import cats.syntax.applicative._ -import cats.syntax.either._ +import cats.syntax.applicative.* +import cats.syntax.either.* import cats.{Applicative, Monad} import endless.core.data.{EventsFolder, Folded} diff --git a/core/src/main/scala/endless/core/interpret/EntityT.scala b/core/src/main/scala/endless/core/interpret/EntityT.scala index 76cbf631..8801986f 100644 --- a/core/src/main/scala/endless/core/interpret/EntityT.scala +++ b/core/src/main/scala/endless/core/interpret/EntityT.scala @@ -1,12 +1,12 @@ package endless.core.interpret -import cats.conversions.all._ +import cats.conversions.all.* import cats.data.{Chain, NonEmptyChain} import cats.effect.kernel.Clock -import cats.syntax.applicative._ -import cats.syntax.either._ -import cats.syntax.flatMap._ -import cats.syntax.functor._ +import cats.syntax.applicative.* +import cats.syntax.either.* +import cats.syntax.flatMap.* +import cats.syntax.functor.* import cats.{Applicative, Functor, Monad, ~>} import endless.core.data.{EventsFolder, Folded} import endless.core.entity.Entity @@ -81,7 +81,7 @@ object EntityT extends EntityRunFunctions { * be injected with an instance of `Entity[F[_]]` interpreted with EntityT[F, S, E, *] */ implicit def instance[F[_]: Monad, S, E] - : Entity[EntityT[F, S, E, *], S, E] with Monad[EntityT[F, S, E, *]] = + : Entity[EntityT[F, S, E, *], S, E] & Monad[EntityT[F, S, E, *]] = new EntityTLiftInstance[F, S, E] implicit def clockForEntityT[F[_]: Functor: Clock, S, E](implicit diff --git a/core/src/main/scala/endless/core/interpret/EntityTLiftInstance.scala b/core/src/main/scala/endless/core/interpret/EntityTLiftInstance.scala index 3fa6cafd..ed75a80b 100644 --- a/core/src/main/scala/endless/core/interpret/EntityTLiftInstance.scala +++ b/core/src/main/scala/endless/core/interpret/EntityTLiftInstance.scala @@ -1,12 +1,12 @@ package endless.core.interpret import cats.Monad -import cats.conversions.all._ +import cats.conversions.all.* import cats.data.NonEmptyChain -import cats.syntax.applicative._ -import cats.syntax.either._ -import cats.syntax.flatMap._ -import cats.syntax.functor._ +import cats.syntax.applicative.* +import cats.syntax.either.* +import cats.syntax.flatMap.* +import cats.syntax.functor.* import endless.core.entity.Entity class EntityTLiftInstance[F[_], S, E](implicit fMonad: Monad[F]) @@ -38,7 +38,7 @@ class EntityTLiftInstance[F[_], S, E](implicit fMonad: Monad[F]) override def read: EntityT[F, S, E, Option[S]] = EntityT.reader[F, S, E] override def write(event: E, other: E*): EntityT[F, S, E, Unit] = - EntityT.writer(NonEmptyChain(event, other: _*)) + EntityT.writer(NonEmptyChain(event, other *)) def pure[A](x: A): EntityT[F, S, E, A] = monad.pure(x) diff --git a/core/src/main/scala/endless/core/protocol/CommandSender.scala b/core/src/main/scala/endless/core/protocol/CommandSender.scala index db54c852..8b365272 100644 --- a/core/src/main/scala/endless/core/protocol/CommandSender.scala +++ b/core/src/main/scala/endless/core/protocol/CommandSender.scala @@ -1,7 +1,7 @@ package endless.core.protocol import cats.{Functor, ~>} -import cats.syntax.functor._ +import cats.syntax.functor.* /** `CommandSender[F, ID]` provides a natural transformation to deliver an outgoing command to where * the entity resides and decode the reply as a simple value in the `F` context. diff --git a/core/src/test/scala/endless/core/entity/EffectorSuite.scala b/core/src/test/scala/endless/core/entity/EffectorSuite.scala index f9a5ca47..05760310 100644 --- a/core/src/test/scala/endless/core/entity/EffectorSuite.scala +++ b/core/src/test/scala/endless/core/entity/EffectorSuite.scala @@ -3,8 +3,8 @@ package endless.core.entity import cats.effect.IO import cats.effect.kernel.Ref import munit.ScalaCheckEffectSuite -import org.scalacheck.effect.PropF._ -import scala.concurrent.duration._ +import org.scalacheck.effect.PropF.* +import scala.concurrent.duration.* class EffectorSuite extends munit.CatsEffectSuite with ScalaCheckEffectSuite { test("ifKnown with state") { diff --git a/core/src/test/scala/endless/core/entity/StateReaderHelpersSuite.scala b/core/src/test/scala/endless/core/entity/StateReaderHelpersSuite.scala index 63f11909..77a91862 100644 --- a/core/src/test/scala/endless/core/entity/StateReaderHelpersSuite.scala +++ b/core/src/test/scala/endless/core/entity/StateReaderHelpersSuite.scala @@ -1,6 +1,6 @@ package endless.core.entity import cats.data.EitherT -import cats.syntax.either._ +import cats.syntax.either.* import cats.{Id, Monad} import org.scalacheck.Prop.forAll @@ -15,7 +15,7 @@ class StateReaderHelpersSuite extends munit.ScalaCheckSuite { } } - property("ifKnown with no state") { + test("ifKnown with no state") { val entity = new TestEntity(None) assertEquals( entity.ifKnown(identity)(Error.EntityNotFound).left.getOrElse(fail("non-empty state")), @@ -33,7 +33,7 @@ class StateReaderHelpersSuite extends munit.ScalaCheckSuite { } } - property("ifUnknown with no state") { + test("ifUnknown with no state") { val entity = new TestEntity(None) assertEquals( entity.ifUnknown("foo")(_ => Error.EntityAlreadyExists).getOrElse(fail("non-empty state")), @@ -51,7 +51,7 @@ class StateReaderHelpersSuite extends munit.ScalaCheckSuite { } } - property("ifKnownF with no state") { + test("ifKnownF with no state") { val entity = new TestEntity(None) assertEquals( entity.ifKnownF(identity)(Error.EntityNotFound).left.getOrElse(fail("non-empty state")), @@ -72,7 +72,7 @@ class StateReaderHelpersSuite extends munit.ScalaCheckSuite { } } - property("ifUnknownF with no state") { + test("ifUnknownF with no state") { val entity = new TestEntity(None) assertEquals( entity.ifUnknownF("foo")(_ => Error.EntityAlreadyExists).getOrElse(fail("non-empty state")), @@ -92,7 +92,7 @@ class StateReaderHelpersSuite extends munit.ScalaCheckSuite { } } - property("ifKnownFE with no state") { + test("ifKnownFE with no state") { val entity = new TestEntity(None) assertEquals( entity @@ -116,7 +116,7 @@ class StateReaderHelpersSuite extends munit.ScalaCheckSuite { } } - property("ifUnknownFE with no state") { + test("ifUnknownFE with no state") { val entity = new TestEntity(None) assertEquals( entity @@ -138,7 +138,7 @@ class StateReaderHelpersSuite extends munit.ScalaCheckSuite { } } - property("ifKnownT with no state") { + test("ifKnownT with no state") { val entity = new TestEntity(None) assertEquals( entity @@ -162,7 +162,7 @@ class StateReaderHelpersSuite extends munit.ScalaCheckSuite { } } - property("ifUnknownT with no state") { + test("ifUnknownT with no state") { val entity = new TestEntity(None) assertEquals( entity diff --git a/core/src/test/scala/endless/core/interpret/DurableEntityTSuite.scala b/core/src/test/scala/endless/core/interpret/DurableEntityTSuite.scala index 654c33c6..6d40e4ac 100644 --- a/core/src/test/scala/endless/core/interpret/DurableEntityTSuite.scala +++ b/core/src/test/scala/endless/core/interpret/DurableEntityTSuite.scala @@ -1,15 +1,15 @@ package endless.core.interpret import cats.laws.discipline.MonadTests -import cats.syntax.eq._ -import cats.syntax.flatMap._ +import cats.syntax.eq.* +import cats.syntax.flatMap.* import cats.tests.ListWrapper -import cats.tests.ListWrapper._ +import cats.tests.ListWrapper.* import cats.{Applicative, Eq, Functor, Monad} -import endless.core.interpret.DurableEntityT._ +import endless.core.interpret.DurableEntityT.* import munit.DisciplineSuite import org.scalacheck.Arbitrary -import org.scalacheck.Arbitrary._ +import org.scalacheck.Arbitrary.* import org.typelevel.log4cats.Logger class DurableEntityTSuite extends DisciplineSuite { diff --git a/core/src/test/scala/endless/core/interpret/EntityTSuite.scala b/core/src/test/scala/endless/core/interpret/EntityTSuite.scala index 7ba61cd1..5568db64 100644 --- a/core/src/test/scala/endless/core/interpret/EntityTSuite.scala +++ b/core/src/test/scala/endless/core/interpret/EntityTSuite.scala @@ -2,17 +2,17 @@ package endless.core.interpret import cats.data.{Chain, NonEmptyChain} import cats.laws.discipline.{FunctorTests, MonadTests} -import cats.syntax.either._ -import cats.syntax.eq._ -import cats.syntax.flatMap._ +import cats.syntax.either.* +import cats.syntax.eq.* +import cats.syntax.flatMap.* import cats.tests.ListWrapper -import cats.tests.ListWrapper._ +import cats.tests.ListWrapper.* import cats.{Applicative, Eq, Functor, Monad} import endless.core.event.EventApplier -import endless.core.interpret.EntityT._ +import endless.core.interpret.EntityT.* import munit.DisciplineSuite import org.scalacheck.Arbitrary -import org.scalacheck.Arbitrary._ +import org.scalacheck.Arbitrary.* import org.typelevel.log4cats.Logger class EntityTSuite extends DisciplineSuite { @@ -70,24 +70,27 @@ class EntityTSuite extends DisciplineSuite { } test("reader folds state") { - val List(Right((events, Some(folded)))) = (EntityT - .writer[ListWrapper, State, Event]( - NonEmptyChain(event1, event2, event3) - ) >> EntityT.reader) - .run(Some(Chain.empty)) - .list - - assert(events === Chain(event1, event2, event3)) - assert(folded === Chain(event1, event2, event3)) + val result = (EntityT.writer[ListWrapper, State, Event]( + NonEmptyChain(event1, event2, event3) + ) >> EntityT.reader).run(Option(Chain.empty)).list.head + result match { + case Right((events, Some(folded))) => + assert(events === Chain(event1, event2, event3)) + assert(folded === Chain(event1, event2, event3)) + case _ => fail("reader failed") + } } test("failing folder fails when reader is involved") { - val List(Left(error)) = (EntityT + val result = (EntityT .writer[ListWrapper, State, Event](NonEmptyChain.one(event1)) >> EntityT.reader) .run(Some(Chain.empty))((_: Option[State], _: Event) => "error".asLeft) .list - - assert(error === "error") + .head + result match { + case Left("error") => () + case _ => fail("reader failed") + } } test("liftK is resolved by Logger auto-derive") { diff --git a/example/src/main/protobuf/package.proto b/example/src/main/protobuf/package.proto new file mode 100644 index 00000000..2ebfc8f4 --- /dev/null +++ b/example/src/main/protobuf/package.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; +import "scalapb/scalapb.proto"; + +package endless.example.proto; + +option (scalapb.options) = { + scope: PACKAGE + scala3_sources: true +}; \ No newline at end of file diff --git a/example/src/main/scala/endless/example/adapter/BookingEventAdapter.scala b/example/src/main/scala/endless/example/adapter/BookingEventAdapter.scala index 1cc36559..91278069 100644 --- a/example/src/main/scala/endless/example/adapter/BookingEventAdapter.scala +++ b/example/src/main/scala/endless/example/adapter/BookingEventAdapter.scala @@ -2,8 +2,9 @@ package endless.example.adapter import com.google.protobuf.timestamp.Timestamp import endless.example.data.{Booking, BookingEvent, LatLon} -import endless.example.proto.booking.events._ -import endless.example.proto.booking.models._ +import endless.example.proto.booking.events.* +import endless.example.proto.booking.models.* +import cats.syntax.show.* import endless.example.proto.booking.{events => proto} class BookingEventAdapter { @@ -11,7 +12,7 @@ class BookingEventAdapter { event match { case BookingEvent.BookingPlaced(bookingID, time, origin, destination, passengerCount) => proto.BookingPlacedV1( - BookingID(bookingID.id.toString), + BookingID(bookingID.show), Timestamp(time.getEpochSecond, time.getNano), LatLonV1(origin.lat, origin.lon), LatLonV1(destination.lat, destination.lon), diff --git a/example/src/main/scala/endless/example/app/HttpServer.scala b/example/src/main/scala/endless/example/app/HttpServer.scala index 60ce1526..5f62ece9 100644 --- a/example/src/main/scala/endless/example/app/HttpServer.scala +++ b/example/src/main/scala/endless/example/app/HttpServer.scala @@ -1,17 +1,17 @@ package endless.example.app import cats.effect.{IO, Resource} -import cats.syntax.applicative._ -import cats.syntax.either._ -import cats.syntax.show._ +import cats.syntax.applicative.* +import cats.syntax.either.* +import cats.syntax.show.* import endless.example.algebra.{BookingsAlg, VehiclesAlg} import endless.example.data.Booking.BookingID import endless.example.data.Vehicle.VehicleID -import endless.example.data._ -import io.circe.generic.auto._ +import endless.example.data.* +import io.circe.generic.auto.* import org.http4s.blaze.server.BlazeServerBuilder -import org.http4s.circe.CirceEntityCodec._ -import org.http4s.dsl.io._ +import org.http4s.circe.CirceEntityCodec.* +import org.http4s.dsl.io.* import org.http4s.server.Server import org.http4s.{HttpRoutes, Request} diff --git a/example/src/main/scala/endless/example/app/akka/AkkaApp.scala b/example/src/main/scala/endless/example/app/akka/AkkaApp.scala index 42bf46c0..1e51cf29 100644 --- a/example/src/main/scala/endless/example/app/akka/AkkaApp.scala +++ b/example/src/main/scala/endless/example/app/akka/AkkaApp.scala @@ -7,7 +7,7 @@ import akka.persistence.testkit.{ } import akka.persistence.typed.{EventAdapter, EventSeq, SnapshotAdapter} import akka.util.Timeout -import cats.effect._ +import cats.effect.* import com.typesafe.config.ConfigFactory import endless.core.interpret.{ DurableBehaviorInterpreter, @@ -15,23 +15,23 @@ import endless.core.interpret.{ BehaviorInterpreter, RepositoryInterpreter } -import endless.example.algebra._ +import endless.example.algebra.* import endless.example.app.HttpServer import endless.example.app.impl.{Availabilities, Bookings, Vehicles} import endless.example.data.Booking.BookingID import endless.example.data.Vehicle.VehicleID -import endless.example.data._ -import endless.example.logic._ +import endless.example.data.* +import endless.example.logic.* import endless.runtime.akka.deploy.AkkaCluster import endless.runtime.akka.deploy.AkkaDeployer.AkkaDeploymentParameters import endless.runtime.akka.deploy.AkkaDurableDeployer.AkkaDurableDeploymentParameters -import endless.runtime.akka.syntax.deploy._ +import endless.runtime.akka.syntax.deploy.* import org.http4s.server.Server import org.typelevel.log4cats.Logger import org.typelevel.log4cats.slf4j.Slf4jLogger import scala.concurrent.ExecutionContext -import scala.concurrent.duration._ +import scala.concurrent.duration.* object AkkaApp extends Bookings with Vehicles with Availabilities { @@ -112,7 +112,7 @@ object AkkaApp extends Bookings with Vehicles with Availabilities { ]( RepositoryInterpreter.lift(ShardedBookings(_)), BehaviorInterpreter.lift(BookingEntity(_)), - SideEffectInterpreter.lift((_, _) => BookingSideEffect()) + SideEffectInterpreter.lift((_, _) => new BookingSideEffect()) ), deployDurableRepository[IO, VehicleID, Vehicle, VehicleAlg, VehiclesAlg]( RepositoryInterpreter.lift(ShardedVehicles(_)), diff --git a/example/src/main/scala/endless/example/app/akka/Main.scala b/example/src/main/scala/endless/example/app/akka/Main.scala index eae46e6e..3e557acf 100644 --- a/example/src/main/scala/endless/example/app/akka/Main.scala +++ b/example/src/main/scala/endless/example/app/akka/Main.scala @@ -1,6 +1,6 @@ package endless.example.app.akka -import cats.effect._ +import cats.effect.* object Main extends IOApp { def run(args: List[String]): IO[ExitCode] = AkkaApp(8080).useForever.as(ExitCode.Success) diff --git a/example/src/main/scala/endless/example/app/impl/Availabilities.scala b/example/src/main/scala/endless/example/app/impl/Availabilities.scala index 411ff1b6..49df7eb5 100644 --- a/example/src/main/scala/endless/example/app/impl/Availabilities.scala +++ b/example/src/main/scala/endless/example/app/impl/Availabilities.scala @@ -2,14 +2,14 @@ package endless.example.app.impl import cats.Monad import cats.effect.Async -import cats.syntax.applicative._ -import cats.syntax.flatMap._ -import cats.syntax.show._ +import cats.syntax.applicative.* +import cats.syntax.flatMap.* +import cats.syntax.show.* import endless.example.algebra.AvailabilityAlg import org.typelevel.log4cats.Logger import java.time.Instant -import scala.concurrent.duration._ +import scala.concurrent.duration.* trait Availabilities { implicit def alwaysAvailable[F[_]: Logger: Monad: Async]: AvailabilityAlg[F] = diff --git a/example/src/main/scala/endless/example/app/impl/Bookings.scala b/example/src/main/scala/endless/example/app/impl/Bookings.scala index 781ed59b..f752290e 100644 --- a/example/src/main/scala/endless/example/app/impl/Bookings.scala +++ b/example/src/main/scala/endless/example/app/impl/Bookings.scala @@ -1,6 +1,6 @@ package endless.example.app.impl -import cats.syntax.show._ +import cats.syntax.show.* import endless.core.entity.EntityNameProvider import endless.core.protocol.EntityIDCodec import endless.example.adapter.BookingEventAdapter diff --git a/example/src/main/scala/endless/example/app/impl/Vehicles.scala b/example/src/main/scala/endless/example/app/impl/Vehicles.scala index 4fde9cac..5554a3fa 100644 --- a/example/src/main/scala/endless/example/app/impl/Vehicles.scala +++ b/example/src/main/scala/endless/example/app/impl/Vehicles.scala @@ -1,6 +1,6 @@ package endless.example.app.impl -import cats.syntax.show._ +import cats.syntax.show.* import endless.core.entity.EntityNameProvider import endless.core.protocol.EntityIDCodec import endless.example.adapter.VehicleStateAdapter diff --git a/example/src/main/scala/endless/example/app/pekko/PekkoApp.scala b/example/src/main/scala/endless/example/app/pekko/PekkoApp.scala index 4fbbc3bf..d9bf4998 100644 --- a/example/src/main/scala/endless/example/app/pekko/PekkoApp.scala +++ b/example/src/main/scala/endless/example/app/pekko/PekkoApp.scala @@ -6,7 +6,7 @@ import org.apache.pekko.persistence.testkit.{ PersistenceTestKitPlugin } import org.apache.pekko.util.Timeout -import cats.effect._ +import cats.effect.* import com.typesafe.config.ConfigFactory import endless.core.interpret.{ DurableBehaviorInterpreter, @@ -14,14 +14,14 @@ import endless.core.interpret.{ BehaviorInterpreter, RepositoryInterpreter } -import endless.example.algebra._ +import endless.example.algebra.* import endless.example.app.HttpServer import endless.example.app.impl.{Availabilities, Bookings, Vehicles} import endless.example.data.Booking.BookingID import endless.example.data.Vehicle.VehicleID -import endless.example.data._ -import endless.example.logic._ -import endless.runtime.pekko.syntax.deploy._ +import endless.example.data.* +import endless.example.logic.* +import endless.runtime.pekko.syntax.deploy.* import endless.runtime.pekko.deploy.PekkoCluster import endless.runtime.pekko.deploy.PekkoDeployer.PekkoDeploymentParameters import endless.runtime.pekko.deploy.PekkoDurableDeployer.PekkoDurableDeploymentParameters @@ -30,7 +30,7 @@ import org.http4s.server.Server import org.typelevel.log4cats.Logger import org.typelevel.log4cats.slf4j.Slf4jLogger import scala.concurrent.ExecutionContext -import scala.concurrent.duration._ +import scala.concurrent.duration.* object PekkoApp extends Bookings with Vehicles with Availabilities { @@ -115,7 +115,7 @@ object PekkoApp extends Bookings with Vehicles with Availabilities { ]( RepositoryInterpreter.lift(ShardedBookings(_)), BehaviorInterpreter.lift(BookingEntity(_)), - SideEffectInterpreter.lift { case (_, _) => BookingSideEffect() } + SideEffectInterpreter.lift { case (_, _) => new BookingSideEffect() } ), deployDurableRepository[IO, VehicleID, Vehicle, VehicleAlg, VehiclesAlg]( RepositoryInterpreter.lift(ShardedVehicles(_)), diff --git a/example/src/main/scala/endless/example/data/Booking.scala b/example/src/main/scala/endless/example/data/Booking.scala index e4bea203..7ae20c72 100644 --- a/example/src/main/scala/endless/example/data/Booking.scala +++ b/example/src/main/scala/endless/example/data/Booking.scala @@ -1,7 +1,8 @@ package endless.example.data import cats.Show -import endless.example.data.Booking._ +import cats.implicits.toContravariantOps +import endless.example.data.Booking.* import java.time.Instant import java.util.UUID @@ -16,10 +17,10 @@ final case class Booking( ) object Booking { - final case class BookingID(id: UUID) extends AnyVal + final case class BookingID(id: UUID) object BookingID { def fromString(str: String): BookingID = BookingID(UUID.fromString(str)) - implicit val show: Show[BookingID] = Show.show(_.id.toString) + implicit val show: Show[BookingID] = Show.catsShowForUUID.contramap(_.id) } sealed trait Status object Status { diff --git a/example/src/main/scala/endless/example/data/BookingEvent.scala b/example/src/main/scala/endless/example/data/BookingEvent.scala index d632ef47..2e2f1ddd 100644 --- a/example/src/main/scala/endless/example/data/BookingEvent.scala +++ b/example/src/main/scala/endless/example/data/BookingEvent.scala @@ -16,7 +16,7 @@ object BookingEvent { ) extends BookingEvent final case class OriginChanged(newOrigin: LatLon) extends BookingEvent final case class DestinationChanged(newDestination: LatLon) extends BookingEvent - final object BookingAccepted extends BookingEvent - final object BookingRejected extends BookingEvent - final object BookingCancelled extends BookingEvent + object BookingAccepted extends BookingEvent + object BookingRejected extends BookingEvent + object BookingCancelled extends BookingEvent } diff --git a/example/src/main/scala/endless/example/data/LatLon.scala b/example/src/main/scala/endless/example/data/LatLon.scala index 7078d85e..be7e5d81 100644 --- a/example/src/main/scala/endless/example/data/LatLon.scala +++ b/example/src/main/scala/endless/example/data/LatLon.scala @@ -2,7 +2,7 @@ package endless.example.data import cats.Show import cats.kernel.Eq -import cats.syntax.show._ +import cats.syntax.show.* final case class LatLon(lat: Double, lon: Double) diff --git a/example/src/main/scala/endless/example/data/Speed.scala b/example/src/main/scala/endless/example/data/Speed.scala index 1dd635c7..d3059f2a 100644 --- a/example/src/main/scala/endless/example/data/Speed.scala +++ b/example/src/main/scala/endless/example/data/Speed.scala @@ -1,9 +1,9 @@ package endless.example.data import cats.Show -import cats.syntax.show._ +import cats.syntax.show.* -final case class Speed(metersPerSecond: Double) extends AnyVal +final case class Speed(metersPerSecond: Double) object Speed { implicit val show: Show[Speed] = Show.show(speed => show"${speed.metersPerSecond} m/s") diff --git a/example/src/main/scala/endless/example/data/Vehicle.scala b/example/src/main/scala/endless/example/data/Vehicle.scala index 734c07fd..e46c8300 100644 --- a/example/src/main/scala/endless/example/data/Vehicle.scala +++ b/example/src/main/scala/endless/example/data/Vehicle.scala @@ -1,6 +1,7 @@ package endless.example.data import cats.Show +import cats.implicits.toContravariantOps import java.util.UUID @@ -10,6 +11,6 @@ object Vehicle { final case class VehicleID(id: UUID) extends AnyVal object VehicleID { def fromString(str: String): VehicleID = VehicleID(UUID.fromString(str)) - implicit val show: Show[VehicleID] = Show.show(_.id.toString) + implicit val show: Show[VehicleID] = Show.catsShowForUUID.contramap(_.id) } } diff --git a/example/src/main/scala/endless/example/logic/BookingEntity.scala b/example/src/main/scala/endless/example/logic/BookingEntity.scala index ec70fcbe..7bbaf80e 100644 --- a/example/src/main/scala/endless/example/logic/BookingEntity.scala +++ b/example/src/main/scala/endless/example/logic/BookingEntity.scala @@ -2,16 +2,16 @@ package endless.example.logic import cats.data.EitherT import cats.effect.kernel.Clock -import cats.syntax.applicative._ -import cats.syntax.eq._ -import cats.syntax.flatMap._ -import cats.syntax.show._ +import cats.syntax.applicative.* +import cats.syntax.eq.* +import cats.syntax.flatMap.* +import cats.syntax.show.* import endless.\/ import endless.core.entity.Entity import endless.example.algebra.BookingAlg import endless.example.algebra.BookingAlg.{BookingAlreadyExists, BookingUnknown, CancelError} -import endless.example.data.Booking._ -import endless.example.data.BookingEvent._ +import endless.example.data.Booking.* +import endless.example.data.BookingEvent.* import endless.example.data.{Booking, BookingEvent, LatLon} import org.typelevel.log4cats.Logger @@ -20,7 +20,7 @@ import java.time.Instant //#definition final case class BookingEntity[F[_]: Logger: Clock](entity: Entity[F, Booking, BookingEvent]) extends BookingAlg[F] { - import entity._ + import entity.* def place( bookingID: BookingID, diff --git a/example/src/main/scala/endless/example/logic/BookingEventApplier.scala b/example/src/main/scala/endless/example/logic/BookingEventApplier.scala index 47e109e8..f779d2d7 100644 --- a/example/src/main/scala/endless/example/logic/BookingEventApplier.scala +++ b/example/src/main/scala/endless/example/logic/BookingEventApplier.scala @@ -1,9 +1,9 @@ package endless.example.logic -import cats.syntax.either._ +import cats.syntax.either.* import endless.\/ import endless.core.event.EventApplier -import endless.example.data.BookingEvent._ +import endless.example.data.BookingEvent.* import endless.example.data.{Booking, BookingEvent} //#definition diff --git a/example/src/main/scala/endless/example/logic/BookingSideEffect.scala b/example/src/main/scala/endless/example/logic/BookingSideEffect.scala index fff2c7e4..fbd55138 100644 --- a/example/src/main/scala/endless/example/logic/BookingSideEffect.scala +++ b/example/src/main/scala/endless/example/logic/BookingSideEffect.scala @@ -1,9 +1,9 @@ package endless.example.logic -import cats.syntax.applicative._ -import cats.syntax.flatMap._ -import cats.syntax.functor._ -import cats.syntax.show._ +import cats.syntax.applicative.* +import cats.syntax.flatMap.* +import cats.syntax.functor.* +import cats.syntax.show.* import cats.{Applicative, Monad} import endless.core.entity.{Effector, SideEffect} import endless.example.algebra.{AvailabilityAlg, BookingAlg} @@ -11,14 +11,14 @@ import endless.example.data.Booking import endless.example.data.Booking.Status import org.typelevel.log4cats.Logger -import scala.concurrent.duration._ +import scala.concurrent.duration.* //#definition -final case class BookingSideEffect[F[_]: Logger: Monad]()(implicit +class BookingSideEffect[F[_]: Logger: Monad]()(implicit availabilityAlg: AvailabilityAlg[F] ) extends SideEffect[F, Booking, BookingAlg] { def apply(effector: Effector[F, Booking, BookingAlg]): F[Unit] = { - import effector._ + import effector.* val availabilityProcess: Booking => F[Unit] = booking => booking.status match { diff --git a/example/src/main/scala/endless/example/logic/VehicleEntity.scala b/example/src/main/scala/endless/example/logic/VehicleEntity.scala index 62ff3a80..0db78b6d 100644 --- a/example/src/main/scala/endless/example/logic/VehicleEntity.scala +++ b/example/src/main/scala/endless/example/logic/VehicleEntity.scala @@ -1,8 +1,8 @@ package endless.example.logic -import cats.syntax.flatMap._ -import cats.syntax.functor._ -import cats.syntax.show._ +import cats.syntax.flatMap.* +import cats.syntax.functor.* +import cats.syntax.show.* import endless.core.entity.DurableEntity import endless.example.algebra.VehicleAlg import endless.example.data.{LatLon, Speed, Vehicle} @@ -10,7 +10,7 @@ import org.typelevel.log4cats.Logger final case class VehicleEntity[F[_]: Logger](entity: DurableEntity[F, Vehicle]) extends VehicleAlg[F] { - import entity._ + import entity.* def setSpeed(speed: Speed): F[Unit] = ifKnownElse(_ => diff --git a/example/src/main/scala/endless/example/logic/VehicleSideEffect.scala b/example/src/main/scala/endless/example/logic/VehicleSideEffect.scala index 5981a2d2..f7cf2713 100644 --- a/example/src/main/scala/endless/example/logic/VehicleSideEffect.scala +++ b/example/src/main/scala/endless/example/logic/VehicleSideEffect.scala @@ -2,13 +2,13 @@ package endless.example.logic import cats.Applicative import cats.effect.{Concurrent, Ref} -import cats.syntax.flatMap._ -import cats.syntax.functor._ +import cats.syntax.flatMap.* +import cats.syntax.functor.* import endless.core.entity.{Effector, SideEffect} import endless.example.algebra.VehicleAlg import endless.example.data.Vehicle -import scala.concurrent.duration._ +import scala.concurrent.duration.* class VehicleSideEffect[F[_]: Concurrent](justRecoveredRef: Ref[F, Boolean]) extends SideEffect[F, Vehicle, VehicleAlg] { diff --git a/example/src/main/scala/endless/example/protocol/BookingCommandProtocol.scala b/example/src/main/scala/endless/example/protocol/BookingCommandProtocol.scala index f99ae609..44d653c2 100644 --- a/example/src/main/scala/endless/example/protocol/BookingCommandProtocol.scala +++ b/example/src/main/scala/endless/example/protocol/BookingCommandProtocol.scala @@ -1,21 +1,22 @@ package endless.example.protocol -import cats.conversions.all._ +import cats.conversions.all.* +import cats.syntax.show.* import com.google.protobuf.timestamp.Timestamp import endless.\/ import endless.core.protocol.{CommandSender, Decoder, IncomingCommand} import endless.example.algebra.BookingAlg -import endless.example.algebra.BookingAlg._ +import endless.example.algebra.BookingAlg.* import endless.example.data.Booking.BookingID -import endless.example.data._ +import endless.example.data.* import endless.example.proto.booking.commands.BookingCommand.Command -import endless.example.proto.booking.commands._ +import endless.example.proto.booking.commands.* import endless.example.proto.booking.commands.{BookingCommand, PlaceBookingV1} import endless.example.proto.booking.models.BookingStatusV1.Status import endless.example.proto.booking.replies import endless.example.proto.booking.{models => proto} import endless.protobuf.{ProtobufCommandProtocol, ProtobufDecoder} -import BookingCommandProtocol._ +import BookingCommandProtocol.* import endless.example.proto.booking.replies.UnitReply import java.time.Instant @@ -39,7 +40,7 @@ class BookingCommandProtocol extends ProtobufCommandProtocol[BookingID, BookingA BookingCommand.of( Command.PlaceBookingV1( PlaceBookingV1( - proto.BookingID(bookingID.id.toString), + proto.BookingID(bookingID.show), Timestamp.of(time.getEpochSecond, time.getNano), passengerCount, proto.LatLonV1(origin.lat, origin.lon), @@ -68,7 +69,7 @@ class BookingCommandProtocol extends ProtobufCommandProtocol[BookingID, BookingA case replies.GetBookingReply(replies.GetBookingReply.Reply.Booking(booking), _) => Right( Booking( - BookingID(UUID.fromString(booking.id.value)), + BookingID.fromString(booking.id.value), Instant.ofEpochSecond(booking.time.seconds, booking.time.nanos), LatLon(booking.origin.lat, booking.origin.lon), LatLon(booking.destination.lat, booking.destination.lon), @@ -222,7 +223,7 @@ class BookingCommandProtocol extends ProtobufCommandProtocol[BookingID, BookingA replies.PlaceBookingReply( replies.PlaceBookingReply.Reply.AlreadyExists( replies.BookingAlreadyExistsV1( - proto.BookingID(bookingAlreadyExists.bookingID.id.toString) + proto.BookingID(bookingAlreadyExists.bookingID.show) ) ) ) @@ -244,7 +245,7 @@ class BookingCommandProtocol extends ProtobufCommandProtocol[BookingID, BookingA replies.GetBookingReply( replies.GetBookingReply.Reply.Booking( proto.BookingV1( - proto.BookingID(booking.id.id.toString), + proto.BookingID(booking.id.show), Timestamp(booking.time.getEpochSecond, booking.time.getNano), proto.LatLonV1(booking.origin.lat, booking.origin.lon), proto.LatLonV1(booking.destination.lat, booking.destination.lon), @@ -318,7 +319,7 @@ class BookingCommandProtocol extends ProtobufCommandProtocol[BookingID, BookingA case Left(BookingWasRejected(bookingID)) => replies.CancelBookingReply( replies.CancelBookingReply.Reply.Rejected( - replies.BookingWasRejectedV1(proto.BookingID(bookingID.id.toString)) + replies.BookingWasRejectedV1(proto.BookingID(bookingID.show)) ) ) case Right(_) => diff --git a/example/src/main/scala/endless/example/protocol/VehicleCommandProtocol.scala b/example/src/main/scala/endless/example/protocol/VehicleCommandProtocol.scala index a7efd578..eb8cd119 100644 --- a/example/src/main/scala/endless/example/protocol/VehicleCommandProtocol.scala +++ b/example/src/main/scala/endless/example/protocol/VehicleCommandProtocol.scala @@ -5,7 +5,7 @@ import endless.example.algebra.VehicleAlg import endless.example.data.Vehicle.VehicleID import endless.example.data.{LatLon, Speed} import endless.example.proto.vehicle.commands.VehicleCommand.Command -import endless.example.proto.vehicle.commands._ +import endless.example.proto.vehicle.commands.* import endless.example.proto.vehicle.models.{LatLonV1, SpeedV1} import endless.example.proto.vehicle.replies.{ GetPositionReply, diff --git a/example/src/test/scala/endless/example/AkkaExampleAppSuite.scala b/example/src/test/scala/endless/example/AkkaExampleAppSuite.scala index 93edbc4e..affd72fd 100644 --- a/example/src/test/scala/endless/example/AkkaExampleAppSuite.scala +++ b/example/src/test/scala/endless/example/AkkaExampleAppSuite.scala @@ -5,5 +5,5 @@ import endless.example.app.akka.AkkaApp class AkkaExampleAppSuite extends munit.CatsEffectSuite with ExampleAppSuite { lazy val port: Int = 8080 private val akkaServer = ResourceSuiteLocalFixture("akka-server", AkkaApp(port)) - override def munitFixtures: Seq[Fixture[_]] = List(akkaServer, client) + override def munitFixtures: Seq[Fixture[?]] = List(akkaServer, client) } diff --git a/example/src/test/scala/endless/example/ExampleAppSuite.scala b/example/src/test/scala/endless/example/ExampleAppSuite.scala index 4b954ede..9dcbeda8 100644 --- a/example/src/test/scala/endless/example/ExampleAppSuite.scala +++ b/example/src/test/scala/endless/example/ExampleAppSuite.scala @@ -1,22 +1,22 @@ package endless.example import cats.effect.IO -import cats.syntax.show._ -import endless.example.app.HttpServer._ +import cats.syntax.show.* +import endless.example.app.HttpServer.* import endless.example.data.Booking.BookingID import endless.example.data.Vehicle.VehicleID import endless.example.data.{Booking, LatLon, Speed} -import io.circe.generic.auto._ -import org.http4s.Method._ +import io.circe.generic.auto.* +import org.http4s.Method.* import org.http4s.Uri import org.http4s.blaze.client.BlazeClientBuilder -import org.http4s.circe.CirceEntityCodec._ +import org.http4s.circe.CirceEntityCodec.* import org.http4s.client.Client -import org.http4s.client.dsl.io._ +import org.http4s.client.dsl.io.* import java.time.Instant import java.util.UUID -import scala.concurrent.duration._ +import scala.concurrent.duration.* trait ExampleAppSuite { self: munit.CatsEffectSuite => protected val client: Fixture[Client[IO]] = diff --git a/example/src/test/scala/endless/example/PekkoExampleAppSuite.scala b/example/src/test/scala/endless/example/PekkoExampleAppSuite.scala index c6f8b1ed..04f07bce 100644 --- a/example/src/test/scala/endless/example/PekkoExampleAppSuite.scala +++ b/example/src/test/scala/endless/example/PekkoExampleAppSuite.scala @@ -5,5 +5,5 @@ import endless.example.app.pekko.PekkoApp class PekkoExampleAppSuite extends munit.CatsEffectSuite with ExampleAppSuite { lazy val port: Int = 8081 private val pekkoServer = ResourceSuiteLocalFixture("pekko-server", PekkoApp(port)) - override def munitFixtures: Seq[Fixture[_]] = List(pekkoServer, client) + override def munitFixtures: Seq[Fixture[?]] = List(pekkoServer, client) } diff --git a/example/src/test/scala/endless/example/logic/BookingEntitySuite.scala b/example/src/test/scala/endless/example/logic/BookingEntitySuite.scala index 118f3c87..0b441376 100644 --- a/example/src/test/scala/endless/example/logic/BookingEntitySuite.scala +++ b/example/src/test/scala/endless/example/logic/BookingEntitySuite.scala @@ -2,11 +2,11 @@ package endless.example.logic import cats.data.Chain import cats.effect.IO import endless.core.interpret.EntityT -import endless.core.interpret.EntityT._ +import endless.core.interpret.EntityT.* import endless.example.algebra.BookingAlg.{BookingAlreadyExists, BookingUnknown, BookingWasRejected} -import endless.example.data.BookingEvent._ +import endless.example.data.BookingEvent.* import endless.example.data.{Booking, BookingEvent, LatLon} -import org.scalacheck.effect.PropF._ +import org.scalacheck.effect.PropF.* import org.typelevel.log4cats.testing.TestingLogger //#example @@ -19,7 +19,7 @@ class BookingEntitySuite private implicit val eventApplier: BookingEventApplier = new BookingEventApplier test("place booking") { - forAllF { booking: Booking => + forAllF { (booking: Booking) => bookingAlg .place( booking.id, @@ -67,7 +67,7 @@ class BookingEntitySuite //#example test("place booking when it already exists") { - forAllF { booking: Booking => + forAllF { (booking: Booking) => bookingAlg .place( booking.id, @@ -86,7 +86,7 @@ class BookingEntitySuite } test("get booking") { - forAllF { booking: Booking => + forAllF { (booking: Booking) => bookingAlg.get .run(Some(booking)) .map { @@ -121,7 +121,7 @@ class BookingEntitySuite } test("change origin when unknown") { - forAllF { newOrigin: LatLon => + forAllF { (newOrigin: LatLon) => bookingAlg .changeOrigin(newOrigin) .run(None) @@ -146,7 +146,7 @@ class BookingEntitySuite } test("change destination when unknown") { - forAllF { newDestination: LatLon => + forAllF { (newDestination: LatLon) => bookingAlg .changeDestination(newDestination) .run(None) @@ -170,7 +170,7 @@ class BookingEntitySuite } test("cancel booking") { - forAllF { booking: Booking => + forAllF { (booking: Booking) => bookingAlg.cancel.run(Some(booking)).map { case Right((events, _)) => assertEquals(events, Chain(BookingCancelled)) @@ -180,7 +180,7 @@ class BookingEntitySuite } test("cancel booking when rejected") { - forAllF { booking: Booking => + forAllF { (booking: Booking) => bookingAlg.cancel.run(Some(booking.copy(status = Booking.Status.Rejected))).map { case Right((_, Left(bookingWasRejected))) => assertEquals(bookingWasRejected, BookingWasRejected(booking.id)) @@ -197,7 +197,7 @@ class BookingEntitySuite } test("notify capacity available") { - forAllF { booking: Booking => + forAllF { (booking: Booking) => bookingAlg.notifyCapacity(true).run(Some(booking)).map { case Right((events, _)) => assertEquals(events, Chain(BookingAccepted)) @@ -214,7 +214,7 @@ class BookingEntitySuite } test("notify capacity unavailable") { - forAllF { booking: Booking => + forAllF { (booking: Booking) => bookingAlg.notifyCapacity(false).run(Some(booking)).map { case Right((events, _)) => assertEquals(events, Chain(BookingRejected)) diff --git a/example/src/test/scala/endless/example/logic/BookingEventApplierSuite.scala b/example/src/test/scala/endless/example/logic/BookingEventApplierSuite.scala index d33f3266..38d78dbe 100644 --- a/example/src/test/scala/endless/example/logic/BookingEventApplierSuite.scala +++ b/example/src/test/scala/endless/example/logic/BookingEventApplierSuite.scala @@ -1,13 +1,13 @@ package endless.example.logic -import endless.example.data.BookingEvent._ +import endless.example.data.BookingEvent.* import endless.example.data.{Booking, LatLon} -import org.scalacheck.Prop._ +import org.scalacheck.Prop.* //#example class BookingEventApplierSuite extends munit.ScalaCheckSuite with Generators { property("booking placed when unknown") { - forAll { booking: Booking => + forAll { (booking: Booking) => val fold = new BookingEventApplier()( None, BookingPlaced( @@ -23,7 +23,7 @@ class BookingEventApplierSuite extends munit.ScalaCheckSuite with Generators { } property("booking placed when known") { - forAll { booking: Booking => + forAll { (booking: Booking) => val fold = new BookingEventApplier()( Some(booking), BookingPlaced( @@ -46,7 +46,7 @@ class BookingEventApplierSuite extends munit.ScalaCheckSuite with Generators { } property("origin changed when unknown") { - forAll { newOrigin: LatLon => + forAll { (newOrigin: LatLon) => val fold = new BookingEventApplier()(None, OriginChanged(newOrigin)) assert(fold.isLeft) } @@ -60,45 +60,44 @@ class BookingEventApplierSuite extends munit.ScalaCheckSuite with Generators { } property("destination changed when unknown") { - forAll { newDestination: LatLon => + forAll { (newDestination: LatLon) => val fold = new BookingEventApplier()(None, DestinationChanged(newDestination)) assert(fold.isLeft) } } property("booking accepted when known") { - forAll { booking: Booking => + forAll { (booking: Booking) => val fold = new BookingEventApplier()(Some(booking), BookingAccepted) assertEquals(fold.toOption.flatMap(_.map(_.status)), Option(Booking.Status.Accepted)) } } - property("booking accepted when unknown") { + test("booking accepted when unknown") { val fold = new BookingEventApplier()(None, BookingAccepted) assert(fold.isLeft) - } property("booking rejected when known") { - forAll { booking: Booking => + forAll { (booking: Booking) => val fold = new BookingEventApplier()(Some(booking), BookingRejected) assertEquals(fold.toOption.flatMap(_.map(_.status)), Option(Booking.Status.Rejected)) } } - property("booking rejected when unknown") { + test("booking rejected when unknown") { val fold = new BookingEventApplier()(None, BookingRejected) assert(fold.isLeft) } property("booking cancelled when known") { - forAll { booking: Booking => + forAll { (booking: Booking) => val fold = new BookingEventApplier()(Some(booking), BookingCancelled) assertEquals(fold.toOption.flatMap(_.map(_.status)), Option(Booking.Status.Cancelled)) } } - property("booking cancelled when unknown") { + test("booking cancelled when unknown") { val fold = new BookingEventApplier()(None, BookingCancelled) assert(fold.isLeft) } diff --git a/example/src/test/scala/endless/example/logic/BookingSideEffectSuite.scala b/example/src/test/scala/endless/example/logic/BookingSideEffectSuite.scala index 97dce3ef..61f958e9 100644 --- a/example/src/test/scala/endless/example/logic/BookingSideEffectSuite.scala +++ b/example/src/test/scala/endless/example/logic/BookingSideEffectSuite.scala @@ -1,18 +1,18 @@ package endless.example.logic import cats.effect.IO -import cats.syntax.either._ -import cats.syntax.show._ +import cats.syntax.either.* +import cats.syntax.show.* import endless.\/ import endless.core.entity.Effector import endless.core.entity.Effector.PassivationState import endless.example.algebra.{AvailabilityAlg, BookingAlg} import endless.example.data.{Booking, LatLon} -import org.scalacheck.effect.PropF._ +import org.scalacheck.effect.PropF.forAllF import org.typelevel.log4cats.testing.TestingLogger import java.time.Instant -import scala.concurrent.duration._ +import scala.concurrent.duration.* //#example class BookingSideEffectSuite @@ -23,47 +23,47 @@ class BookingSideEffectSuite implicit private def availabilityAlg: AvailabilityAlg[IO] = (_: Instant, _: Int) => IO(true) test("some state logs") { - forAllF { booking: Booking => + forAllF { (booking: Booking) => val acceptedBooking = booking.copy(status = Booking.Status.Accepted) for { effector <- Effector.apply[IO, Booking, BookingAlg]( new SelfEntity {}, Some(acceptedBooking) ) - _ <- BookingSideEffect().apply(effector) + _ <- new BookingSideEffect().apply(effector) _ <- assertIO(logger.logged.map(_.map(_.message).last), show"State is now $acceptedBooking") } yield () } } test("some state passivates after one hour") { - forAllF { booking: Booking => + forAllF { (booking: Booking) => for { effector <- Effector.apply[IO, Booking, BookingAlg]( new SelfEntity {}, Some(booking.copy(status = Booking.Status.Accepted)) ) - _ <- BookingSideEffect().apply(effector) + _ <- new BookingSideEffect().apply(effector) _ <- assertIO(effector.passivationState, Effector.PassivationState.After(1.hour)) } yield () } } test("passivates immediately when cancelled") { - forAllF { booking: Booking => + forAllF { (booking: Booking) => for { effector <- Effector.apply[IO, Booking, BookingAlg]( new SelfEntity {}, Some(booking.copy(status = Booking.Status.Cancelled)) ) - _ <- BookingSideEffect().apply(effector) + _ <- new BookingSideEffect().apply(effector) _ <- assertIO(effector.passivationState, PassivationState.After(Duration.Zero)) } yield () } } test("notifies availability when pending and does not passivate") { - forAllF { booking: Booking => + forAllF { (booking: Booking) => for { effector <- Effector.apply[IO, Booking, BookingAlg]( new SelfEntity { @@ -76,7 +76,7 @@ class BookingSideEffectSuite }, Some(booking.copy(status = Booking.Status.Pending)) ) - _ <- BookingSideEffect().apply(effector) + _ <- new BookingSideEffect().apply(effector) } yield () } } diff --git a/example/src/test/scala/endless/example/logic/Generators.scala b/example/src/test/scala/endless/example/logic/Generators.scala index 9af70663..0fa0976b 100644 --- a/example/src/test/scala/endless/example/logic/Generators.scala +++ b/example/src/test/scala/endless/example/logic/Generators.scala @@ -31,7 +31,7 @@ trait Generators { Gen.uuid.map(uuid => BookingAlreadyExists(BookingID(uuid))) implicit val bookingUnknownGen: Gen[BookingUnknown.type] = Gen.const(BookingUnknown) implicit val cancelErrorGen: Gen[CancelError] = - Gen.oneOf(bookingUnknownGen, bookingIDGen.map(BookingWasRejected)) + Gen.oneOf(bookingUnknownGen, bookingIDGen.map(BookingWasRejected.apply)) implicit val arbBookingID: Arbitrary[BookingID] = Arbitrary(bookingIDGen) implicit val arbBooking: Arbitrary[Booking] = Arbitrary(bookingGen) diff --git a/example/src/test/scala/endless/example/logic/VehicleEntitySuite.scala b/example/src/test/scala/endless/example/logic/VehicleEntitySuite.scala index 825ddb51..d24c5e7c 100644 --- a/example/src/test/scala/endless/example/logic/VehicleEntitySuite.scala +++ b/example/src/test/scala/endless/example/logic/VehicleEntitySuite.scala @@ -2,9 +2,9 @@ package endless.example.logic import cats.effect.IO import endless.core.interpret.DurableEntityT -import endless.core.interpret.DurableEntityT._ +import endless.core.interpret.DurableEntityT.* import endless.example.data.{LatLon, Speed, Vehicle} -import org.scalacheck.effect.PropF._ +import org.scalacheck.effect.PropF.* import org.typelevel.log4cats.testing.TestingLogger class VehicleEntitySuite @@ -15,7 +15,7 @@ class VehicleEntitySuite private val vehicleAlg = VehicleEntity(DurableEntityT.instance[IO, Vehicle]) test("set position") { - forAllF { latLon: LatLon => + forAllF { (latLon: LatLon) => vehicleAlg .setPosition(latLon) .run(State.None) @@ -29,7 +29,7 @@ class VehicleEntitySuite } test("set speed") { - forAllF { speed: Speed => + forAllF { (speed: Speed) => vehicleAlg .setSpeed(speed) .run(State.None) diff --git a/example/src/test/scala/endless/example/logic/VehicleSideEffectSuite.scala b/example/src/test/scala/endless/example/logic/VehicleSideEffectSuite.scala index c8123e63..d0bc5aa1 100644 --- a/example/src/test/scala/endless/example/logic/VehicleSideEffectSuite.scala +++ b/example/src/test/scala/endless/example/logic/VehicleSideEffectSuite.scala @@ -4,7 +4,7 @@ import cats.effect.IO import endless.core.entity.Effector import endless.example.algebra.VehicleAlg import endless.example.data.{LatLon, Speed, Vehicle} -import scala.concurrent.duration._ +import scala.concurrent.duration.* class VehicleSideEffectSuite extends munit.CatsEffectSuite { diff --git a/pekko-runtime/src/main/protobuf/command.proto b/pekko-runtime/src/main/protobuf/command.proto index a547a5b4..8db0a35c 100644 --- a/pekko-runtime/src/main/protobuf/command.proto +++ b/pekko-runtime/src/main/protobuf/command.proto @@ -1,4 +1,9 @@ syntax = "proto2"; +import "scalapb/scalapb.proto"; + +option (scalapb.options) = { + scala3_sources: true +}; package endless.runtime.pekko.serializer.proto; option optimize_for = SPEED; diff --git a/pekko-runtime/src/main/scala/endless/runtime/pekko/EntityPassivator.scala b/pekko-runtime/src/main/scala/endless/runtime/pekko/EntityPassivator.scala index e5adbb60..0b81ff07 100644 --- a/pekko-runtime/src/main/scala/endless/runtime/pekko/EntityPassivator.scala +++ b/pekko-runtime/src/main/scala/endless/runtime/pekko/EntityPassivator.scala @@ -5,17 +5,17 @@ import org.apache.pekko.actor.typed.scaladsl.ActorContext import org.apache.pekko.cluster.sharding.typed.scaladsl.{ClusterSharding, EntityContext} import cats.Applicative import cats.effect.kernel.{Ref, Sync} -import cats.syntax.eq._ -import cats.syntax.flatMap._ -import cats.syntax.functor._ +import cats.syntax.eq.* +import cats.syntax.flatMap.* +import cats.syntax.functor.* import endless.core.entity.Effector.PassivationState import scala.concurrent.duration.{Duration, FiniteDuration} private[pekko] class EntityPassivator[F[_]: Sync](upcomingPassivation: Ref[F, Option[Cancellable]])( implicit - entityContext: EntityContext[_], - actorContext: ActorContext[_] + entityContext: EntityContext[?], + actorContext: ActorContext[?] ) { private lazy val passivateMessage = ClusterSharding.Passivate(actorContext.self) private lazy val passivate = Sync[F].delay(entityContext.shard.tell(passivateMessage)) @@ -44,8 +44,8 @@ private[pekko] class EntityPassivator[F[_]: Sync](upcomingPassivation: Ref[F, Op object EntityPassivator { def apply[F[_]: Sync](implicit - entityContext: EntityContext[_], - actorContext: ActorContext[_] + entityContext: EntityContext[?], + actorContext: ActorContext[?] ): F[EntityPassivator[F]] = Ref.of[F, Option[Cancellable]](Option.empty[Cancellable]).map(new EntityPassivator(_)) } diff --git a/pekko-runtime/src/main/scala/endless/runtime/pekko/ShardingCommandSender.scala b/pekko-runtime/src/main/scala/endless/runtime/pekko/ShardingCommandSender.scala index b950511c..c2b45a9e 100644 --- a/pekko-runtime/src/main/scala/endless/runtime/pekko/ShardingCommandSender.scala +++ b/pekko-runtime/src/main/scala/endless/runtime/pekko/ShardingCommandSender.scala @@ -3,9 +3,9 @@ package endless.runtime.pekko import org.apache.pekko.cluster.sharding.typed.scaladsl.{ClusterSharding, EntityTypeKey} import org.apache.pekko.util.Timeout import cats.effect.kernel.Async -import cats.syntax.applicative._ -import cats.syntax.flatMap._ -import cats.syntax.show._ +import cats.syntax.applicative.* +import cats.syntax.flatMap.* +import cats.syntax.show.* import cats.~> import endless.core.entity.EntityNameProvider import endless.core.protocol.{CommandSender, EntityIDEncoder, OutgoingCommand} diff --git a/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/PekkoCluster.scala b/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/PekkoCluster.scala index 7ad59291..03b04aad 100644 --- a/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/PekkoCluster.scala +++ b/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/PekkoCluster.scala @@ -5,12 +5,12 @@ import org.apache.pekko.actor.CoordinatedShutdown import org.apache.pekko.actor.typed.ActorSystem import org.apache.pekko.cluster.{Cluster, MemberStatus} import org.apache.pekko.cluster.sharding.typed.scaladsl.ClusterSharding -import cats.effect.kernel.implicits._ +import cats.effect.kernel.implicits.* import cats.effect.kernel.{Async, Deferred, Resource, Sync} import cats.effect.std.Dispatcher import cats.implicits.catsSyntaxApplicativeError -import cats.syntax.flatMap._ -import cats.syntax.functor._ +import cats.syntax.flatMap.* +import cats.syntax.functor.* import org.typelevel.log4cats.Logger import scala.concurrent.TimeoutException @@ -27,7 +27,7 @@ import scala.concurrent.duration.{Duration, DurationInt} * effects dispatcher tied to the cluster resource scope */ final case class PekkoCluster[F[_]: Async]( - system: ActorSystem[_], + system: ActorSystem[?], dispatcher: Dispatcher[F], cluster: Cluster, sharding: ClusterSharding @@ -61,7 +61,7 @@ object PekkoCluster { * seconds by default). */ def managedResource[F[_]: Async: Logger]( - createActorSystem: => ActorSystem[_], + createActorSystem: => ActorSystem[?], catsEffectReleaseTimeout: Duration = 5.seconds, pekkoReleaseTimeout: Duration = 5.seconds ): Resource[F, PekkoCluster[F]] = @@ -111,7 +111,7 @@ object PekkoCluster { ) private def createCluster[F[_]: Async: Logger]( - createActorSystem: => ActorSystem[_], + createActorSystem: => ActorSystem[?], dispatcher: Dispatcher[F] ) = for { system <- Sync[F].delay(createActorSystem) diff --git a/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/PekkoDeployer.scala b/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/PekkoDeployer.scala index 2993c6d9..432fee91 100644 --- a/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/PekkoDeployer.scala +++ b/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/PekkoDeployer.scala @@ -1,12 +1,12 @@ package endless.runtime.pekko.deploy import cats.effect.kernel.{Async, Resource} -import endless.core.entity._ +import endless.core.entity.* import endless.core.event.EventApplier -import endless.core.interpret._ +import endless.core.interpret.* import endless.core.protocol.{CommandProtocol, CommandSender, EntityIDCodec} import endless.runtime.pekko.ShardingCommandSender -import endless.runtime.pekko.data._ +import endless.runtime.pekko.data.* import endless.runtime.pekko.deploy.PekkoDeployer.{ DeployedPekkoRepository, PekkoDeploymentParameters @@ -35,7 +35,7 @@ trait PekkoDeployer extends Deployer { eventApplier: EventApplier[S, E], parameters: PekkoDeploymentParameters[F, S, E] ): Resource[F, DeployedPekkoRepository[F, RepositoryAlg]] = { - import parameters._ + import parameters.* implicit val sharding: ClusterSharding = pekkoCluster.sharding implicit val sender: CommandSender[F, ID] = ShardingCommandSender[F, ID] for { diff --git a/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/PekkoDurableDeployer.scala b/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/PekkoDurableDeployer.scala index 74dde3d8..34e8f201 100644 --- a/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/PekkoDurableDeployer.scala +++ b/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/PekkoDurableDeployer.scala @@ -1,11 +1,11 @@ package endless.runtime.pekko.deploy import cats.effect.kernel.{Async, Resource} -import endless.core.entity._ -import endless.core.interpret._ +import endless.core.entity.* +import endless.core.interpret.* import endless.core.protocol.{CommandProtocol, CommandSender, EntityIDCodec} import endless.runtime.pekko.ShardingCommandSender -import endless.runtime.pekko.data._ +import endless.runtime.pekko.data.* import endless.runtime.pekko.deploy.PekkoDurableDeployer.{ DeployedPekkoDurableRepository, PekkoDurableDeploymentParameters @@ -34,7 +34,7 @@ trait PekkoDurableDeployer extends DurableDeployer { commandProtocol: CommandProtocol[ID, Alg], parameters: PekkoDurableDeploymentParameters[F, S] ): Resource[F, DeployedPekkoDurableRepository[F, RepositoryAlg]] = { - import parameters._ + import parameters.* implicit val sharding: ClusterSharding = pekkoCluster.sharding implicit val sender: CommandSender[F, ID] = ShardingCommandSender[F, ID] diff --git a/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/internal/DurableShardedEntityDeployer.scala b/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/internal/DurableShardedEntityDeployer.scala index 3dbb2a52..fa137e54 100644 --- a/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/internal/DurableShardedEntityDeployer.scala +++ b/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/internal/DurableShardedEntityDeployer.scala @@ -8,16 +8,16 @@ import org.apache.pekko.persistence.typed.state.scaladsl.{DurableStateBehavior, import org.apache.pekko.persistence.typed.state.{RecoveryCompleted, RecoveryFailed} import cats.effect.kernel.Async import cats.effect.std.Dispatcher -import cats.syntax.applicative._ -import cats.syntax.flatMap._ -import cats.syntax.functor._ -import cats.syntax.show._ -import endless.core.entity._ +import cats.syntax.applicative.* +import cats.syntax.flatMap.* +import cats.syntax.functor.* +import cats.syntax.show.* +import endless.core.entity.* import endless.core.interpret.DurableEntityT.{DurableEntityT, State} -import endless.core.interpret._ +import endless.core.interpret.* import endless.core.protocol.{CommandProtocol, CommandSender, EntityIDCodec} import endless.runtime.pekko.EntityPassivator -import endless.runtime.pekko.data._ +import endless.runtime.pekko.data.* import org.typelevel.log4cats.Logger private[deploy] class DurableShardedEntityDeployer[F[_]: Async: Logger, S, ID: EntityIDCodec, Alg[_[ @@ -108,7 +108,7 @@ private[deploy] class DurableShardedEntityDeployer[F[_]: Async: Logger, S, ID: E // run the effector asynchronously, as it can describe long-running processes dispatcher.unsafeRunAndForget(handleSideEffect(state)) ) - .thenReply(command.replyTo) { _: Option[S] => + .thenReply(command.replyTo) { (_: Option[S]) => Reply(incomingCommand.replyEncoder.encode(reply)) } .pure[F] diff --git a/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/internal/EventSourcedShardedEntityDeployer.scala b/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/internal/EventSourcedShardedEntityDeployer.scala index 8e071a58..a38c3936 100644 --- a/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/internal/EventSourcedShardedEntityDeployer.scala +++ b/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/internal/EventSourcedShardedEntityDeployer.scala @@ -7,17 +7,17 @@ import org.apache.pekko.persistence.typed.scaladsl.{Effect, EventSourcedBehavior import org.apache.pekko.persistence.typed.{PersistenceId, RecoveryCompleted, RecoveryFailed} import cats.effect.kernel.Async import cats.effect.std.Dispatcher -import cats.syntax.applicative._ -import cats.syntax.flatMap._ -import cats.syntax.functor._ -import cats.syntax.show._ +import cats.syntax.applicative.* +import cats.syntax.flatMap.* +import cats.syntax.functor.* +import cats.syntax.show.* import endless.core.entity.{Effector, EntityNameProvider, Sharding, SideEffect} import endless.core.event.EventApplier import endless.core.interpret.{EntityT, SideEffectInterpreter} import endless.core.protocol.{CommandProtocol, CommandSender, EntityIDCodec} import endless.runtime.pekko.EntityPassivator import endless.runtime.pekko.data.{Command, Reply} -import endless.runtime.pekko.deploy.internal.EventSourcedShardedEntityDeployer._ +import endless.runtime.pekko.deploy.internal.EventSourcedShardedEntityDeployer.* import org.typelevel.log4cats.Logger private[deploy] class EventSourcedShardedEntityDeployer[F[ @@ -115,7 +115,7 @@ private[deploy] class EventSourcedShardedEntityDeployer[F[ // run the effector asynchronously, as it can describe long-running processes dispatcher.unsafeRunAndForget(handleSideEffect(state)) ) - .thenReply(command.replyTo) { _: Option[S] => + .thenReply(command.replyTo) { (_: Option[S]) => Reply(incomingCommand.replyEncoder.encode(reply)) } .pure[F] diff --git a/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/internal/ShardedRepositoryDeployer.scala b/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/internal/ShardedRepositoryDeployer.scala index 331aa109..9f7589e8 100644 --- a/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/internal/ShardedRepositoryDeployer.scala +++ b/pekko-runtime/src/main/scala/endless/runtime/pekko/deploy/internal/ShardedRepositoryDeployer.scala @@ -11,11 +11,11 @@ import org.apache.pekko.cluster.sharding.typed.scaladsl.{ import org.apache.pekko.util.Timeout import cats.effect.kernel.{Async, Resource} import cats.effect.std.Dispatcher -import endless.core.entity._ +import endless.core.entity.* import endless.core.interpret.RepositoryInterpreter import endless.core.protocol.{CommandProtocol, CommandSender, EntityIDEncoder} import endless.runtime.pekko.ShardingCommandSender -import endless.runtime.pekko.data._ +import endless.runtime.pekko.data.* import endless.runtime.pekko.deploy.PekkoCluster import org.typelevel.log4cats.Logger diff --git a/pekko-runtime/src/main/scala/endless/runtime/pekko/protobuf/ScalaPbSerializer.scala b/pekko-runtime/src/main/scala/endless/runtime/pekko/protobuf/ScalaPbSerializer.scala index 590e6858..d1b03ae9 100644 --- a/pekko-runtime/src/main/scala/endless/runtime/pekko/protobuf/ScalaPbSerializer.scala +++ b/pekko-runtime/src/main/scala/endless/runtime/pekko/protobuf/ScalaPbSerializer.scala @@ -19,7 +19,7 @@ import java.util.concurrent.atomic.AtomicReference ) class ScalaPbSerializer(val system: ExtendedActorSystem) extends BaseSerializer { private val classToCompanionMapRef = - new AtomicReference[Map[Class[_], GeneratedMessageCompanion[_]]](Map.empty) + new AtomicReference[Map[Class[?], GeneratedMessageCompanion[?]]](Map.empty) override def toBinary(o: AnyRef): Array[Byte] = o match { case e: scalapb.GeneratedMessage => e.toByteArray @@ -28,14 +28,14 @@ class ScalaPbSerializer(val system: ExtendedActorSystem) extends BaseSerializer override def includeManifest: Boolean = true - override def fromBinary(bytes: Array[Byte], manifest: Option[Class[_]]): AnyRef = + override def fromBinary(bytes: Array[Byte], manifest: Option[Class[?]]): AnyRef = manifest match { case Some(clazz) => // noinspection ScalaStyle @scala.annotation.tailrec def messageCompanion( - companion: GeneratedMessageCompanion[_] = null - ): GeneratedMessageCompanion[_] = { + companion: GeneratedMessageCompanion[?] = null + ): GeneratedMessageCompanion[?] = { val classToCompanion = classToCompanionMapRef.get() classToCompanion.get(clazz) match { case Some(cachedCompanion) => cachedCompanion @@ -46,7 +46,7 @@ class ScalaPbSerializer(val system: ExtendedActorSystem) extends BaseSerializer .forName(clazz.getName + "$", true, clazz.getClassLoader) .getField("MODULE$") .get(()) - .asInstanceOf[GeneratedMessageCompanion[_]] + .asInstanceOf[GeneratedMessageCompanion[?]] else companion if ( classToCompanionMapRef.compareAndSet( diff --git a/pekko-runtime/src/main/scala/endless/runtime/pekko/serializer/CommandSerializer.scala b/pekko-runtime/src/main/scala/endless/runtime/pekko/serializer/CommandSerializer.scala index 1d1102f3..6d4b859f 100644 --- a/pekko-runtime/src/main/scala/endless/runtime/pekko/serializer/CommandSerializer.scala +++ b/pekko-runtime/src/main/scala/endless/runtime/pekko/serializer/CommandSerializer.scala @@ -3,7 +3,7 @@ package endless.runtime.pekko.serializer import org.apache.pekko.actor.typed.ActorRefResolver import org.apache.pekko.actor.typed.scaladsl.adapter.ClassicActorSystemOps import org.apache.pekko.serialization.{BaseSerializer, SerializerWithStringManifest} -import cats.syntax.show._ +import cats.syntax.show.* import com.google.protobuf.ByteString import endless.runtime.pekko.data.Command import endless.runtime.pekko.serializer.CommandSerializer.ManifestKey diff --git a/pekko-runtime/src/test/protobuf/dummy.proto b/pekko-runtime/src/test/protobuf/dummy.proto index 22458fe5..0c276f31 100644 --- a/pekko-runtime/src/test/protobuf/dummy.proto +++ b/pekko-runtime/src/test/protobuf/dummy.proto @@ -1,4 +1,9 @@ syntax = "proto3"; +import "scalapb/scalapb.proto"; + +option (scalapb.options) = { + scala3_sources: true +}; package endless.protobuf.test.proto; diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 5af8ccdd..9b650f5b 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -1,7 +1,7 @@ import sbt.* object Dependencies { - lazy val akkaVersion = "2.6.17" + lazy val akkaVersion = "2.6.20" lazy val akkaActorTyped = "com.typesafe.akka" %% "akka-actor-typed" lazy val akkaPersistenceTyped = "com.typesafe.akka" %% "akka-persistence-typed" lazy val akkaClusterTyped = "com.typesafe.akka" %% "akka-cluster-typed" @@ -102,7 +102,7 @@ object Dependencies { lazy val kittensVersion = "3.1.0" lazy val kittens = Seq("org.typelevel" %% "kittens" % kittensVersion) - lazy val scodecCore = Seq("org.scodec" %% "scodec-core" % "1.11.10") + lazy val scodecCore = Seq("org.scodec" %% "scodec-core" % "2.2.2") lazy val scalapbCustomizations = Seq( "com.thesamet.scalapb" %% "scalapb-runtime" % scalapb.compiler.Version.scalapbVersion % "protobuf" diff --git a/protobuf/src/test/protobuf/dummy.proto b/protobuf/src/test/protobuf/dummy.proto index 22458fe5..0c276f31 100644 --- a/protobuf/src/test/protobuf/dummy.proto +++ b/protobuf/src/test/protobuf/dummy.proto @@ -1,4 +1,9 @@ syntax = "proto3"; +import "scalapb/scalapb.proto"; + +option (scalapb.options) = { + scala3_sources: true +}; package endless.protobuf.test.proto; diff --git a/scodec/src/test/scala/endless/scodec/ScodecCommandProtocolSuite.scala b/scodec/src/test/scala/endless/scodec/ScodecCommandProtocolSuite.scala index fa613f69..eb2c1976 100644 --- a/scodec/src/test/scala/endless/scodec/ScodecCommandProtocolSuite.scala +++ b/scodec/src/test/scala/endless/scodec/ScodecCommandProtocolSuite.scala @@ -3,10 +3,10 @@ import cats.Id import endless.core.protocol.{CommandSender, Decoder, IncomingCommand} import org.scalacheck.Prop.forAll import scodec.Codec -import scodec.codecs.implicits._ +import scodec.Codec.given_Codec_Boolean class ScodecCommandProtocolSuite extends munit.ScalaCheckSuite { - test("scodec command protocol") { + property("scodec command protocol") { forAll { (int: Int, str: String, reply: Boolean, id: String) => implicit val sender: CommandSender[Id, ID] = localCommandSenderWith(reply) val actual = dummyProtocol.clientFor(id).dummy(int, str) @@ -37,8 +37,8 @@ class ScodecCommandProtocolSuite extends munit.ScalaCheckSuite { case class DummyCommand(x: Int, y: String) object DummyCommand { - implicit val scodecDecoder: scodec.Decoder[DummyCommand] = Codec[DummyCommand].asDecoder - implicit val scodecEncoder: scodec.Encoder[DummyCommand] = Codec[DummyCommand].asEncoder + implicit val scodecDecoder: scodec.Decoder[DummyCommand] = Codec.derived[DummyCommand].asDecoder + implicit val scodecEncoder: scodec.Encoder[DummyCommand] = Codec.derived[DummyCommand].asEncoder } type ID = String