diff --git a/.scalafmt.conf b/.scalafmt.conf index b9fd9da18..0c26abfb8 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -2,7 +2,7 @@ version = "3.1.2" runner.dialect = scala213 project { excludePaths = [ - "glob:**/core/src/generated/*.scala", + "glob:**/core/src-*/generated/*.scala", "glob:**/example/src/smithy4s/**/*.scala", "glob:**/schematic-core/src/generated/*.scala", "glob:**/schematic-scalacheck/src/generated/*.scala" diff --git a/build.sbt b/build.sbt index 663f8947e..e1a0312e6 100644 --- a/build.sbt +++ b/build.sbt @@ -159,9 +159,27 @@ lazy val core = projectMatrix ), genDiscoverModels := true, Compile / sourceGenerators := Seq(genSmithyScala(Compile).taskValue), - Compile / sourceGenerators += sourceDirectory - .map(Boilerplate.gen(_, Boilerplate.BoilerplateModule.Core)) - .taskValue, + Compile / sourceGenerators += { + sourceDirectory + .map(Boilerplate.gen(_, Boilerplate.BoilerplateModule.Core)) + .taskValue, + }, + Compile / sourceGenerators += { + sourceDirectory + .zip(scalaVersion) + .map { case (sd, sv) => + val base = sd.getParentFile() + sv match { + case Scala3 => + Boilerplate + .gen(base / "src-3", Boilerplate.BoilerplateModule.Core3) + case _ => + Boilerplate + .gen(base / "src-2", Boilerplate.BoilerplateModule.Core2) + } + } + .taskValue + }, libraryDependencies ++= Seq( Dependencies.collectionsCompat.value, Dependencies.Cats.core.value % Test diff --git a/modules/aws/src/smithy4s/aws/AwsClient.scala b/modules/aws/src/smithy4s/aws/AwsClient.scala index d5c48b512..2aa960732 100644 --- a/modules/aws/src/smithy4s/aws/AwsClient.scala +++ b/modules/aws/src/smithy4s/aws/AwsClient.scala @@ -19,9 +19,9 @@ package smithy4s.aws import cats.MonadThrow import cats.effect.Resource import cats.syntax.all._ -import smithy4s.Transformation import internals.AwsJsonRPCInterpreter +import smithy4s.kinds.PolyFunction5 object AwsClient { @@ -58,7 +58,7 @@ object AwsClient { def build[F[_]: MonadThrow]( awsEnv: AwsEnvironment[F] - ): Transformation[Op, AwsCall[F, *, *, *, *, *]] = + ): PolyFunction5[Op, AwsCall[F, *, *, *, *, *]] = awsProtocol match { case AwsProtocol.AWS_JSON_1_0(_) => new AwsJsonRPCInterpreter[Alg, Op, F]( @@ -79,7 +79,7 @@ object AwsClient { def interpret[F[_]: MonadThrow]( awsEnv: AwsEnvironment[F] - ): AwsClient[Alg, F] = service.transform(build(awsEnv)) + ): AwsClient[Alg, F] = service.fromPolyFunction(build(awsEnv)) } private def initError(msg: String): Throwable = InitialisationError(msg) case class InitialisationError(msg: String) extends Throwable(msg) diff --git a/modules/aws/src/smithy4s/aws/internals/AwsJsonRPCInterpreter.scala b/modules/aws/src/smithy4s/aws/internals/AwsJsonRPCInterpreter.scala index 53ea4ce64..31d085834 100644 --- a/modules/aws/src/smithy4s/aws/internals/AwsJsonRPCInterpreter.scala +++ b/modules/aws/src/smithy4s/aws/internals/AwsJsonRPCInterpreter.scala @@ -19,7 +19,7 @@ package internals import cats.MonadThrow import smithy4s.Endpoint -import smithy4s.Transformation +import smithy4s.kinds._ // format: off /** @@ -31,7 +31,7 @@ private[aws] class AwsJsonRPCInterpreter[Alg[_[_, _, _, _, _]], Op[_,_,_,_,_], F awsEnv: AwsEnvironment[F], contentType: String )(implicit F: MonadThrow[F]) - extends Transformation[Op, AwsCall[F, *, *, *, *, *]] { + extends PolyFunction5[Op, AwsCall[F, *, *, *, *, *]] { // format: on val codecAPI = new json.AwsJsonCodecAPI() @@ -51,7 +51,7 @@ private[aws] class AwsJsonRPCInterpreter[Alg[_[_, _, _, _, _]], Op[_,_,_,_,_], F ) private val awsEndpoints = - new Transformation[ + new PolyFunction5[ Endpoint[Op, *, *, *, *, *], AwsUnaryEndpoint[F, Op, *, *, *, *, *] ] { @@ -59,6 +59,9 @@ private[aws] class AwsJsonRPCInterpreter[Alg[_[_, _, _, _, _]], Op[_,_,_,_,_], F endpoint: Endpoint[Op, I, E, O, SI, SO] ): AwsUnaryEndpoint[F, Op, I, E, O, SI, SO] = new AwsUnaryEndpoint(awsEnv, signer, endpoint, codecAPI) - }.precompute(service.endpoints.map(smithy4s.Kind5.existential(_))) + }.unsafeCacheBy( + service.endpoints.map(Kind5.existential(_)), + identity + ) } diff --git a/modules/codegen/src/smithy4s/codegen/CollisionAvoidance.scala b/modules/codegen/src/smithy4s/codegen/CollisionAvoidance.scala index cbf8ae041..22ac66cf4 100644 --- a/modules/codegen/src/smithy4s/codegen/CollisionAvoidance.scala +++ b/modules/codegen/src/smithy4s/codegen/CollisionAvoidance.scala @@ -259,13 +259,14 @@ object CollisionAvoidance { def getReservedNames: Set[String] = reservedNames - val Transformation_ = NameRef("smithy4s", "Transformation") + val Transformation = NameRef("smithy4s.capability", "Transformation") + val PolyFunction5_ = NameRef("smithy4s.kinds", "PolyFunction5") val Service_ = NameRef("smithy4s", "Service") val Endpoint_ = NameRef("smithy4s", "Endpoint") val NoInput_ = NameRef("smithy4s", "NoInput") val ShapeId_ = NameRef("smithy4s", "ShapeId") val Schema_ = NameRef("smithy4s", "Schema") - val Monadic_ = NameRef("smithy4s", "Monadic") + val FunctorAlgebra_ = NameRef("smithy4s.kinds", "FunctorAlgebra") val StreamingSchema_ = NameRef("smithy4s", "StreamingSchema") val Enumeration_ = NameRef("smithy4s", "Enumeration") val EnumValue_ = NameRef("smithy4s.schema", "EnumValue") diff --git a/modules/codegen/src/smithy4s/codegen/Renderer.scala b/modules/codegen/src/smithy4s/codegen/Renderer.scala index af2707487..17a4a982b 100644 --- a/modules/codegen/src/smithy4s/codegen/Renderer.scala +++ b/modules/codegen/src/smithy4s/codegen/Renderer.scala @@ -166,7 +166,7 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self => val name = s.name val nameGen = NameRef(s"${name}Gen") lines( - line"type ${NameDef(name)}[F[_]] = $Monadic_[$nameGen, F]", + line"type ${NameDef(name)}[F[_]] = $FunctorAlgebra_[$nameGen, F]", block( line"object ${NameRef(name)} extends $Service_.Provider[$nameGen, ${name}Operation]" )( @@ -200,16 +200,7 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self => }, newline, - line"def transform[G[_, _, _, _, _]](transformation : $Transformation_[F, G]) : $genNameRef[G] = new Transformed(transformation)", - block( - line"class $Transformed_[G[_, _, _, _, _]](transformation : $Transformation_[F, G]) extends $genNameRef[G]" - ) { - ops.map { op => - val opName = op.methodName - line"def $opName(${op.renderArgs}) = transformation[${op - .renderAlgParams(genName.name)}](self.$opName(${op.renderParams}))" - } - } + line"def transform : $Transformation.PartiallyApplied[$genName[F]] = new $Transformation.PartiallyApplied[$genName[F]](this)" ), newline, obj( @@ -217,7 +208,7 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self => ext = line"$Service_[$genNameRef, $opTraitNameRef]" )( newline, - line"def apply[F[_]](implicit F: $Monadic_[$genNameRef, F]): F.type = F", + line"def apply[F[_]](implicit F: $FunctorAlgebra_[$genNameRef, F]): F.type = F", newline, renderId(shapeId), newline, @@ -257,12 +248,21 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self => } }, newline, - line"def transform[P[_, _, _, _, _]](transformation: $Transformation_[$opTraitNameRef, P]): $genNameRef[P] = reified.transform(transformation)", + line"def mapK5[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: $genNameRef[P], f: $PolyFunction5_[P, P1]): $genNameRef[P1] = new $Transformed_(alg, f)", newline, - line"def transform[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: $genNameRef[P], transformation: $Transformation_[P, P1]): $genNameRef[P1] = alg.transform(transformation)", + line"def fromPolyFunction[P[_, _, _, _, _]](f: $PolyFunction5_[$opTraitNameRef, P]): $genNameRef[P] = new $Transformed_(reified, f)", + block( + line"class $Transformed_[P[_, _, _, _, _], P1[_ ,_ ,_ ,_ ,_]](alg: $genNameRef[P], f : $PolyFunction5_[P, P1]) extends $genNameRef[P1]" + ) { + ops.map { op => + val opName = op.methodName + line"def $opName(${op.renderArgs}) = f[${op + .renderAlgParams(genName.name)}](alg.$opName(${op.renderParams}))" + } + }, newline, block( - line"def asTransformation[P[_, _, _, _, _]](impl : $genNameRef[P]): $Transformation_[$opTraitNameRef, P] = new $Transformation_[$opTraitNameRef, P]" + line"def toPolyFunction[P[_, _, _, _, _]](impl : $genNameRef[P]): $PolyFunction5_[$opTraitNameRef, P] = new $PolyFunction5_[$opTraitNameRef, P]" ) { if (ops.isEmpty) { line"""def apply[I, E, O, SI, SO](op : $opTraitNameRef[I, E, O, SI, SO]) : P[I, E, O, SI, SO] = sys.error("impossible")""".toLines diff --git a/modules/compliance-tests/src/smithy4s/compliancetests/ClientHttpComplianceTestCase.scala b/modules/compliance-tests/src/smithy4s/compliancetests/ClientHttpComplianceTestCase.scala index 8429c6ad3..ae670f23d 100644 --- a/modules/compliance-tests/src/smithy4s/compliancetests/ClientHttpComplianceTestCase.scala +++ b/modules/compliance-tests/src/smithy4s/compliancetests/ClientHttpComplianceTestCase.scala @@ -37,6 +37,7 @@ import smithy4s.Endpoint import smithy4s.http.PayloadError import smithy4s.Service import smithy4s.ShapeTag +import smithy4s.kinds._ import smithy4s.tests.DefaultSchemaVisitor import scala.concurrent.duration._ @@ -59,7 +60,7 @@ abstract class ClientHttpComplianceTestCase[ import org.http4s.implicits._ private val baseUri = uri"http://localhost/" - def getClient(app: HttpApp[IO]): Resource[IO, smithy4s.Monadic[Alg, IO]] + def getClient(app: HttpApp[IO]): Resource[IO, FunctorAlgebra[Alg, IO]] def codecs: CodecAPI private def matchRequest( @@ -141,7 +142,7 @@ abstract class ClientHttpComplianceTestCase[ input .flatMap { in => service - .asTransformation[R](client) + .toPolyFunction[R](client) .apply(endpoint.wrap(in)) } // deal with the empty response generated in the mock @@ -235,7 +236,7 @@ abstract class ClientHttpComplianceTestCase[ case Left(onError) => onError(doc).flatMap { expectedErr => service - .asTransformation[R](client) + .toPolyFunction[R](client) .apply(endpoint.wrap(dummyInput)) .map { _ => assert.success } .recover { case ex: Throwable => @@ -245,7 +246,7 @@ abstract class ClientHttpComplianceTestCase[ case Right(onOutput) => onOutput(doc).flatMap { expectedOutput => service - .asTransformation[R](client) + .toPolyFunction[R](client) .apply(endpoint.wrap(dummyInput)) .map { output => assert.eql(expectedOutput, output) } } diff --git a/modules/compliance-tests/src/smithy4s/compliancetests/ServerHttpComplianceTestCase.scala b/modules/compliance-tests/src/smithy4s/compliancetests/ServerHttpComplianceTestCase.scala index 224bb6692..5ffe00b8a 100644 --- a/modules/compliance-tests/src/smithy4s/compliancetests/ServerHttpComplianceTestCase.scala +++ b/modules/compliance-tests/src/smithy4s/compliancetests/ServerHttpComplianceTestCase.scala @@ -29,9 +29,9 @@ import smithy4s.Endpoint import smithy4s.http.CodecAPI import smithy4s.Service import smithy4s.ShapeTag +import smithy4s.kinds._ import scala.concurrent.duration._ -import smithy4s.Transformation import smithy4s.ShapeId import smithy4s.Hints import smithy4s.Errorable @@ -52,7 +52,7 @@ abstract class ServerHttpComplianceTestCase[ private val baseUri = uri"http://localhost/" def getServer[Alg2[_[_, _, _, _, _]], Op2[_, _, _, _, _]]( - impl: smithy4s.Monadic[Alg2, IO] + impl: FunctorAlgebra[Alg2, IO] )(implicit s: Service[Alg2, Op2]): Resource[IO, HttpRoutes[IO]] def codecs: CodecAPI @@ -118,9 +118,9 @@ abstract class ServerHttpComplianceTestCase[ name = endpoint.id.toString + "(server|request): " + testCase.id, run = { deferred[I].flatMap { inputDeferred => - val fakeImpl: smithy4s.Monadic[Alg, IO] = - originalService.transform[R]( - new smithy4s.Interpreter[Op, IO] { + val fakeImpl: FunctorAlgebra[Alg, IO] = + originalService.fromPolyFunction[R]( + new FunctorInterpreter[Op, IO] { def apply[I_, E_, O_, SE_, SO_]( op: Op[I_, E_, O_, SE_, SO_] ): IO[O_] = { @@ -159,8 +159,6 @@ abstract class ServerHttpComplianceTestCase[ errorSchema: Option[ErrorResponseTest[_, E]] = None ): ComplianceTest[IO] = { - type R[I_, E_, O_, SE_, SO_] = IO[O_] - ComplianceTest[IO]( name = endpoint.id.toString + "(server|response): " + testCase.id, run = { @@ -189,21 +187,19 @@ abstract class ServerHttpComplianceTestCase[ } } - val fakeImpl: smithy4s.Monadic[NoOpService, IO] = - ammendedService.transform[R] { - new smithy4s.Interpreter[NoInputOp, IO] { - def apply[I_, E_, O_, SE_, SO_]( - op: NoInputOp[I_, E_, O_, SE_, SO_] - ): IO[O_] = { - val doc = testCase.params.getOrElse(Document.obj()) - buildResult match { - case Left(onError) => - onError(doc).flatMap { err => - IO.raiseError[O_](err) - } - case Right(onOutput) => - onOutput(doc).map(_.asInstanceOf[O_]) - } + val fakeImpl: FunctorInterpreter[NoInputOp, IO] = + new FunctorInterpreter[NoInputOp, IO] { + def apply[I_, E_, O_, SE_, SO_]( + op: NoInputOp[I_, E_, O_, SE_, SO_] + ): IO[O_] = { + val doc = testCase.params.getOrElse(Document.obj()) + buildResult match { + case Left(onError) => + onError(doc).flatMap { err => + IO.raiseError[O_](err) + } + case Right(onOutput) => + onOutput(doc).map(_.asInstanceOf[O_]) } } } @@ -235,22 +231,9 @@ abstract class ServerHttpComplianceTestCase[ } private case class NoInputOp[I_, E_, O_, SE_, SO_]() - private trait NoOpService[F[_, _, _, _, _]] { - self => - - def void(): F[Unit, Nothing, Unit, Nothing, Nothing] - def transform[G[_, _, _, _, _]]( - transformation: Transformation[F, G] - ): NoOpService[G] = new Transformed(transformation) - class Transformed[G[_, _, _, _, _]](transformation: Transformation[F, G]) - extends NoOpService[G] { - def void() = - transformation[Unit, Nothing, Unit, Nothing, Nothing](self.void()) - } - } private def prepareService[I, E, O, SE, SO]( endpoint: Endpoint[Op, I, E, O, SE, SO] - ): (Service[NoOpService, NoInputOp], Request[IO]) = { + ): (Service.Reflective[NoInputOp], Request[IO]) = { val amendedEndpoint = // format: off new Endpoint[NoInputOp, Unit, E, O, Nothing, Nothing] { @@ -278,27 +261,12 @@ abstract class ServerHttpComplianceTestCase[ val request = Request[IO](Method.GET, Uri.unsafeFromString("/")) val amendedService = // format: off - new Service[NoOpService, NoInputOp]() { - object reified extends NoOpService[NoInputOp] { - def void() = NoInputOp() - } + new Service.Reflective[NoInputOp] { override def id: ShapeId = ShapeId("custom", "service") override def endpoints: List[Endpoint[NoInputOp, _, _, _, _, _]] = List(amendedEndpoint) override def endpoint[I_, E_, O_, SI_, SO_](op: NoInputOp[I_, E_, O_, SI_, SO_]): (I_, Endpoint[NoInputOp, I_, E_, O_, SI_, SO_]) = ??? override def version: String = originalService.version override def hints: Hints = originalService.hints - - override def transform[P2[_, _, _, _, _]](transformation: Transformation[NoInputOp, P2]): NoOpService[P2] = reified.transform(transformation) - - override def transform[F[_, _, _, _, _], G[_, _, _, _, _]]( - alg: NoOpService[F], - transformation: Transformation[F, G] - ): NoOpService[G] = alg.transform(transformation) - override def asTransformation[P2[_, _, _, _, _]](impl: NoOpService[P2]): Transformation[NoInputOp, P2] = new Transformation[NoInputOp, P2]() { - def apply[I_, E_, O_, SI_, SO_](op : NoInputOp[I_, E_, O_, SI_, SO_]) : P2[I_, E_, O_, SI_, SO_] ={ - impl.void().asInstanceOf[P2[I_, E_, O_, SI_, SO_]] - } - } } // format: on (amendedService, request) diff --git a/modules/compliance-tests/test/src/smithy4s/compliancetests/WeaverComplianceTest.scala b/modules/compliance-tests/test/src/smithy4s/compliancetests/WeaverComplianceTest.scala index 754394d0b..52dea73f9 100644 --- a/modules/compliance-tests/test/src/smithy4s/compliancetests/WeaverComplianceTest.scala +++ b/modules/compliance-tests/test/src/smithy4s/compliancetests/WeaverComplianceTest.scala @@ -52,7 +52,7 @@ object WeaverComplianceTest extends SimpleIOSuite { smithy4s.api.SimpleRestJson() ) { def getServer[Alg2[_[_, _, _, _, _]], Op2[_, _, _, _, _]]( - impl: smithy4s.Monadic[Alg2, IO] + impl: smithy4s.kinds.FunctorAlgebra[Alg2, IO] )(implicit s: Service[Alg2, Op2]): Resource[IO, HttpRoutes[IO]] = SimpleRestJsonBuilder(s).routes(impl).resource diff --git a/modules/core/src-2/ExistentialsPlatformCompat.scala b/modules/core/src-2/ExistentialsPlatformCompat.scala deleted file mode 100644 index 49dc7ac92..000000000 --- a/modules/core/src-2/ExistentialsPlatformCompat.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2021-2022 Disney Streaming - * - * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://disneystreaming.github.io/TOST-1.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smithy4s - -trait ExistentialsPlatformCompat { - - type Existential[F[_]] = F[_] - -} - -object Existential { - - @inline final def wrap[F[_], A](fa: F[A]): F[_] = fa - -} diff --git a/modules/core/src-2/TypeAliases.scala b/modules/core/src-2/TypeAliases.scala deleted file mode 100644 index 4d55ea447..000000000 --- a/modules/core/src-2/TypeAliases.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2021-2022 Disney Streaming - * - * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://disneystreaming.github.io/TOST-1.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smithy4s - -protected[smithy4s] trait TypeAliases { - - type Monadic[Alg[_[_, _, _, _, _]], F[_]] = - Alg[Lambda[(I, E, O, SI, SO) => F[O]]] - - type Interpreter[Op[_, _, _, _, _], F[_]] = - Transformation[Op, Lambda[(I, E, O, SI, SO) => F[O]]] - -} diff --git a/modules/core/src-2/generated/kinds/functorK.scala b/modules/core/src-2/generated/kinds/functorK.scala new file mode 100644 index 000000000..98fb9ad22 --- /dev/null +++ b/modules/core/src-2/generated/kinds/functorK.scala @@ -0,0 +1,76 @@ +/* + * Copyright 2021-2022 Disney Streaming + * + * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://disneystreaming.github.io/TOST-1.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/////// THIS FILE WAS GENERATED AT BUILD TIME, AND CHECKED-IN FOR DISCOVERABILITY /////// + +package smithy4s +package kinds + +trait FunctorK[Alg[_[_]]] { + def mapK[F[_], G[_]](alg: Alg[F], function: PolyFunction[F, G]): Alg[G] +} +object FunctorK { + @inline def apply[Alg[_[_]]](implicit ev: FunctorK[Alg]): FunctorK[Alg] = ev + + implicit def polyfunctionFunctorK[F[_]]: FunctorK[PolyFunction[F, *[_]]] = + new FunctorK[PolyFunction[F, *[_]]] { + def mapK[G[_], H[_]]( + fa: PolyFunction[F, G], + fk: PolyFunction[G, H] + ): PolyFunction[F, H] = fa.andThen(fk) + } +} + +trait FunctorK2[Alg[_[_, _]]] { + def mapK2[F[_, _], G[_, _]]( + alg: Alg[F], + function: PolyFunction2[F, G] + ): Alg[G] +} +object FunctorK2 { + @inline def apply[Alg[_[_, _]]](implicit ev: FunctorK2[Alg]): FunctorK2[Alg] = + ev + + implicit def polyfunctionFunctorK2[F[_, _]] + : FunctorK2[PolyFunction2[F, *[_, _]]] = + new FunctorK2[PolyFunction2[F, *[_, _]]] { + def mapK2[G[_, _], H[_, _]]( + fa: PolyFunction2[F, G], + fk: PolyFunction2[G, H] + ): PolyFunction2[F, H] = fa.andThen(fk) + } +} + +trait FunctorK5[Alg[_[_, _, _, _, _]]] { + def mapK5[F[_, _, _, _, _], G[_, _, _, _, _]]( + alg: Alg[F], + function: PolyFunction5[F, G] + ): Alg[G] +} +object FunctorK5 { + @inline def apply[Alg[_[_, _, _, _, _]]](implicit + ev: FunctorK5[Alg] + ): FunctorK5[Alg] = ev + + implicit def polyfunctionFunctorK5[F[_, _, _, _, _]] + : FunctorK5[PolyFunction5[F, *[_, _, _, _, _]]] = + new FunctorK5[PolyFunction5[F, *[_, _, _, _, _]]] { + def mapK5[G[_, _, _, _, _], H[_, _, _, _, _]]( + fa: PolyFunction5[F, G], + fk: PolyFunction5[G, H] + ): PolyFunction5[F, H] = fa.andThen(fk) + } +} diff --git a/modules/core/src-2/Kind5.scala b/modules/core/src-2/generated/kinds/kinds.scala similarity index 57% rename from modules/core/src-2/Kind5.scala rename to modules/core/src-2/generated/kinds/kinds.scala index 902df97cf..9a0ab67e8 100644 --- a/modules/core/src-2/Kind5.scala +++ b/modules/core/src-2/generated/kinds/kinds.scala @@ -14,15 +14,25 @@ * limitations under the License. */ -package smithy4s +/////// THIS FILE WAS GENERATED AT BUILD TIME, AND CHECKED-IN FOR DISCOVERABILITY /////// -object Kind5 { +package smithy4s +package kinds - type Existential[F[_, _, _, _, _]] = F[_, _, _, _, _] +object Kind1 { + type Existential[F[_]] = F[_] + @inline def existential[F[_], A0](fa: F[A0]): F[_] = fa.asInstanceOf[F[_]] +} - @inline final def existential[F[_, _, _, _, _], I, E, O, SI, SO]( - fa: F[I, E, O, SI, SO] - ): Existential[F] = - fa.asInstanceOf[F[_, _, _, _, _]] +object Kind2 { + type Existential[F[_, _]] = F[_, _] + @inline def existential[F[_, _], A0, A1](fa: F[A0, A1]): F[_, _] = + fa.asInstanceOf[F[_, _]] +} +object Kind5 { + type Existential[F[_, _, _, _, _]] = F[_, _, _, _, _] + @inline def existential[F[_, _, _, _, _], A0, A1, A2, A3, A4]( + fa: F[A0, A1, A2, A3, A4] + ): F[_, _, _, _, _] = fa.asInstanceOf[F[_, _, _, _, _]] } diff --git a/modules/core/src-2/kinds/package.scala b/modules/core/src-2/kinds/package.scala new file mode 100644 index 000000000..2a3a201ed --- /dev/null +++ b/modules/core/src-2/kinds/package.scala @@ -0,0 +1,21 @@ +package smithy4s + +package object kinds { + + // format: off + type FunctorAlgebra[Alg[_[_, _, _, _, _]], F[_]] = Alg[Kind1[F]#toKind5] + type FunctorInterpreter[Op[_, _, _, _, _], F[_]] = PolyFunction5[Op, Kind1[F]#toKind5] + type BiFunctorAlgebra[Alg[_[_, _, _, _, _]], F[_, _]] = Alg[Kind2[F]#toKind5] + type BiFunctorInterpreter[Op[_, _, _, _, _], F[_,_]] = PolyFunction5[Op, Kind2[F]#toKind5] + // format: on + + type Kind1[F[_]] = { + type toKind2[E, O] = F[O] + type toKind5[I, E, O, SI, SO] = F[O] + } + + type Kind2[F[_, _]] = { + type toKind5[I, E, O, SI, SO] = F[E, O] + } + +} diff --git a/modules/core/src-3/ExistentialsPlatformCompat.scala b/modules/core/src-3/ExistentialsPlatformCompat.scala deleted file mode 100644 index abbe2fb4c..000000000 --- a/modules/core/src-3/ExistentialsPlatformCompat.scala +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2021-2022 Disney Streaming - * - * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://disneystreaming.github.io/TOST-1.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smithy4s - -trait ExistentialsPlatformCompat {} - -type Existential[+F[_]] <: (Any { type T }) - -object Existential { - def wrap[F[_], A](fa: F[A]): Existential[F] = fa.asInstanceOf[Existential[F]] -} diff --git a/modules/core/src-3/TypeAliases.scala b/modules/core/src-3/TypeAliases.scala deleted file mode 100644 index 0b282718d..000000000 --- a/modules/core/src-3/TypeAliases.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2021-2022 Disney Streaming - * - * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://disneystreaming.github.io/TOST-1.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smithy4s - -protected[smithy4s] trait TypeAliases { - - type Monadic[Alg[_[_, _, _, _, _]], F[_]] = - Alg[[I, E, O, SI, SO] =>> F[O]] - - type Interpreter[Op[_, _, _, _, _], F[_]] = - Transformation[Op, [I, E, O, SI, SO] =>> F[O]] - -} diff --git a/modules/core/src-3/generated/kinds/functorK.scala b/modules/core/src-3/generated/kinds/functorK.scala new file mode 100644 index 000000000..0471e5baf --- /dev/null +++ b/modules/core/src-3/generated/kinds/functorK.scala @@ -0,0 +1,77 @@ +/* + * Copyright 2021-2022 Disney Streaming + * + * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://disneystreaming.github.io/TOST-1.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/////// THIS FILE WAS GENERATED AT BUILD TIME, AND CHECKED-IN FOR DISCOVERABILITY /////// + +package smithy4s +package kinds + +trait FunctorK[Alg[_[_]]] { + def mapK[F[_], G[_]](alg: Alg[F], function: PolyFunction[F, G]): Alg[G] +} +object FunctorK { + inline def apply[Alg[_[_]]](implicit ev: FunctorK[Alg]): FunctorK[Alg] = ev + + implicit def polyfunctionFunctorK[F[_]] + : FunctorK[[G[_]] =>> PolyFunction[F, G]] = + new FunctorK[[G[_]] =>> PolyFunction[F, G]] { + def mapK[G[_], H[_]]( + fa: PolyFunction[F, G], + fk: PolyFunction[G, H] + ): PolyFunction[F, H] = fa.andThen(fk) + } +} + +trait FunctorK2[Alg[_[_, _]]] { + def mapK2[F[_, _], G[_, _]]( + alg: Alg[F], + function: PolyFunction2[F, G] + ): Alg[G] +} +object FunctorK2 { + inline def apply[Alg[_[_, _]]](implicit ev: FunctorK2[Alg]): FunctorK2[Alg] = + ev + + implicit def polyfunctionFunctorK2[F[_, _]] + : FunctorK2[[G[_, _]] =>> PolyFunction2[F, G]] = + new FunctorK2[[G[_, _]] =>> PolyFunction2[F, G]] { + def mapK2[G[_, _], H[_, _]]( + fa: PolyFunction2[F, G], + fk: PolyFunction2[G, H] + ): PolyFunction2[F, H] = fa.andThen(fk) + } +} + +trait FunctorK5[Alg[_[_, _, _, _, _]]] { + def mapK5[F[_, _, _, _, _], G[_, _, _, _, _]]( + alg: Alg[F], + function: PolyFunction5[F, G] + ): Alg[G] +} +object FunctorK5 { + inline def apply[Alg[_[_, _, _, _, _]]](implicit + ev: FunctorK5[Alg] + ): FunctorK5[Alg] = ev + + implicit def polyfunctionFunctorK5[F[_, _, _, _, _]] + : FunctorK5[[G[_, _, _, _, _]] =>> PolyFunction5[F, G]] = + new FunctorK5[[G[_, _, _, _, _]] =>> PolyFunction5[F, G]] { + def mapK5[G[_, _, _, _, _], H[_, _, _, _, _]]( + fa: PolyFunction5[F, G], + fk: PolyFunction5[G, H] + ): PolyFunction5[F, H] = fa.andThen(fk) + } +} diff --git a/modules/core/src-3/Kind5.scala b/modules/core/src-3/generated/kinds/kinds.scala similarity index 58% rename from modules/core/src-3/Kind5.scala rename to modules/core/src-3/generated/kinds/kinds.scala index b518e4121..9945bbc82 100644 --- a/modules/core/src-3/Kind5.scala +++ b/modules/core/src-3/generated/kinds/kinds.scala @@ -14,15 +14,26 @@ * limitations under the License. */ -package smithy4s +/////// THIS FILE WAS GENERATED AT BUILD TIME, AND CHECKED-IN FOR DISCOVERABILITY /////// -object Kind5 { +package smithy4s +package kinds - type Existential[+F[_, _, _, _, _]] <: (Any { type T }) +object Kind1 { + type Existential[+F[_]] <: (Any { type T }) + inline def existential[F[_], A0](fa: F[A0]): Existential[F] = + fa.asInstanceOf[Existential[F]] +} - def existential[F[_, _, _, _, _], I, E, O, SI, SO]( - fa: F[I, E, O, SI, SO] - ): Existential[F] = +object Kind2 { + type Existential[+F[_, _]] <: (Any { type T }) + inline def existential[F[_, _], A0, A1](fa: F[A0, A1]): Existential[F] = fa.asInstanceOf[Existential[F]] +} +object Kind5 { + type Existential[+F[_, _, _, _, _]] <: (Any { type T }) + inline def existential[F[_, _, _, _, _], A0, A1, A2, A3, A4]( + fa: F[A0, A1, A2, A3, A4] + ): Existential[F] = fa.asInstanceOf[Existential[F]] } diff --git a/modules/core/src-3/kinds/package.scala b/modules/core/src-3/kinds/package.scala new file mode 100644 index 000000000..70aea367f --- /dev/null +++ b/modules/core/src-3/kinds/package.scala @@ -0,0 +1,22 @@ +package smithy4s + +package object kinds { + + // format: off + // Not using type projectors as it messes with type inference when using the algebra + type FunctorAlgebra[Alg[_[_, _, _, _, _]], F[_]] = Alg[[I, E, O, SI, SO] =>> F[O]] + type FunctorInterpreter[Op[_, _, _, _, _], F[_]] = PolyFunction5[Op, [I, E, O, SI, SO] =>> F[O]] + type BiFunctorAlgebra[Alg[_[_, _, _, _, _]], F[_, _]] = Alg[[I, E, O, SI, SO] =>> F[E, O]] + type BiFunctorInterpreter[Op[_, _, _, _, _], F[_, _]] = PolyFunction5[Op, [I, E, O, SI, SO] =>> F[E, O]] + // format: on + + type Kind1[F[_]] = { + type toKind2[E, O] = F[O] + type toKind5[I, E, O, SI, SO] = F[O] + } + + type Kind2[F[_, _]] = { + type toKind5[I, E, O, SI, SO] = F[E, O] + } + +} diff --git a/modules/core/src/generated/PartiallyAppliedStruct.scala b/modules/core/src/generated/PartiallyAppliedStruct.scala deleted file mode 100644 index 38ccf591d..000000000 --- a/modules/core/src/generated/PartiallyAppliedStruct.scala +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2021-2022 Disney Streaming - * - * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://disneystreaming.github.io/TOST-1.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smithy4s -package schema - -class PartiallyAppliedStruct[S] protected[schema](placeholder: ShapeId) { - - def genericArity( - fields: SchemaField[S, _]*)( - const: IndexedSeq[Any] => S) : Schema[S] = - Schema.StructSchema(placeholder, Hints.empty, fields.toVector, const) - - def apply( - fields: Vector[SchemaField[S, _]])( - const: IndexedSeq[Any] => S) : Schema[S] = - Schema.StructSchema(placeholder, Hints.empty, fields, const) - - def apply[A0](a0: SchemaField[S, A0])(const : (A0) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0), arr => const(arr(0).asInstanceOf[A0])) - def apply[A0, A1](a0: SchemaField[S, A0], a1: SchemaField[S, A1])(const : (A0, A1) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1])) - def apply[A0, A1, A2](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2])(const : (A0, A1, A2) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2])) - def apply[A0, A1, A2, A3](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3])(const : (A0, A1, A2, A3) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3])) - def apply[A0, A1, A2, A3, A4](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4])(const : (A0, A1, A2, A3, A4) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4])) - def apply[A0, A1, A2, A3, A4, A5](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5])(const : (A0, A1, A2, A3, A4, A5) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5])) - def apply[A0, A1, A2, A3, A4, A5, A6](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6])(const : (A0, A1, A2, A3, A4, A5, A6) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7])(const : (A0, A1, A2, A3, A4, A5, A6, A7) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7], a8: SchemaField[S, A8])(const : (A0, A1, A2, A3, A4, A5, A6, A7, A8) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7], arr(8).asInstanceOf[A8])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7], a8: SchemaField[S, A8], a9: SchemaField[S, A9])(const : (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7], arr(8).asInstanceOf[A8], arr(9).asInstanceOf[A9])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7], a8: SchemaField[S, A8], a9: SchemaField[S, A9], a10: SchemaField[S, A10])(const : (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7], arr(8).asInstanceOf[A8], arr(9).asInstanceOf[A9], arr(10).asInstanceOf[A10])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7], a8: SchemaField[S, A8], a9: SchemaField[S, A9], a10: SchemaField[S, A10], a11: SchemaField[S, A11])(const : (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7], arr(8).asInstanceOf[A8], arr(9).asInstanceOf[A9], arr(10).asInstanceOf[A10], arr(11).asInstanceOf[A11])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7], a8: SchemaField[S, A8], a9: SchemaField[S, A9], a10: SchemaField[S, A10], a11: SchemaField[S, A11], a12: SchemaField[S, A12])(const : (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7], arr(8).asInstanceOf[A8], arr(9).asInstanceOf[A9], arr(10).asInstanceOf[A10], arr(11).asInstanceOf[A11], arr(12).asInstanceOf[A12])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7], a8: SchemaField[S, A8], a9: SchemaField[S, A9], a10: SchemaField[S, A10], a11: SchemaField[S, A11], a12: SchemaField[S, A12], a13: SchemaField[S, A13])(const : (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7], arr(8).asInstanceOf[A8], arr(9).asInstanceOf[A9], arr(10).asInstanceOf[A10], arr(11).asInstanceOf[A11], arr(12).asInstanceOf[A12], arr(13).asInstanceOf[A13])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7], a8: SchemaField[S, A8], a9: SchemaField[S, A9], a10: SchemaField[S, A10], a11: SchemaField[S, A11], a12: SchemaField[S, A12], a13: SchemaField[S, A13], a14: SchemaField[S, A14])(const : (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7], arr(8).asInstanceOf[A8], arr(9).asInstanceOf[A9], arr(10).asInstanceOf[A10], arr(11).asInstanceOf[A11], arr(12).asInstanceOf[A12], arr(13).asInstanceOf[A13], arr(14).asInstanceOf[A14])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7], a8: SchemaField[S, A8], a9: SchemaField[S, A9], a10: SchemaField[S, A10], a11: SchemaField[S, A11], a12: SchemaField[S, A12], a13: SchemaField[S, A13], a14: SchemaField[S, A14], a15: SchemaField[S, A15])(const : (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7], arr(8).asInstanceOf[A8], arr(9).asInstanceOf[A9], arr(10).asInstanceOf[A10], arr(11).asInstanceOf[A11], arr(12).asInstanceOf[A12], arr(13).asInstanceOf[A13], arr(14).asInstanceOf[A14], arr(15).asInstanceOf[A15])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7], a8: SchemaField[S, A8], a9: SchemaField[S, A9], a10: SchemaField[S, A10], a11: SchemaField[S, A11], a12: SchemaField[S, A12], a13: SchemaField[S, A13], a14: SchemaField[S, A14], a15: SchemaField[S, A15], a16: SchemaField[S, A16])(const : (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7], arr(8).asInstanceOf[A8], arr(9).asInstanceOf[A9], arr(10).asInstanceOf[A10], arr(11).asInstanceOf[A11], arr(12).asInstanceOf[A12], arr(13).asInstanceOf[A13], arr(14).asInstanceOf[A14], arr(15).asInstanceOf[A15], arr(16).asInstanceOf[A16])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7], a8: SchemaField[S, A8], a9: SchemaField[S, A9], a10: SchemaField[S, A10], a11: SchemaField[S, A11], a12: SchemaField[S, A12], a13: SchemaField[S, A13], a14: SchemaField[S, A14], a15: SchemaField[S, A15], a16: SchemaField[S, A16], a17: SchemaField[S, A17])(const : (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7], arr(8).asInstanceOf[A8], arr(9).asInstanceOf[A9], arr(10).asInstanceOf[A10], arr(11).asInstanceOf[A11], arr(12).asInstanceOf[A12], arr(13).asInstanceOf[A13], arr(14).asInstanceOf[A14], arr(15).asInstanceOf[A15], arr(16).asInstanceOf[A16], arr(17).asInstanceOf[A17])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7], a8: SchemaField[S, A8], a9: SchemaField[S, A9], a10: SchemaField[S, A10], a11: SchemaField[S, A11], a12: SchemaField[S, A12], a13: SchemaField[S, A13], a14: SchemaField[S, A14], a15: SchemaField[S, A15], a16: SchemaField[S, A16], a17: SchemaField[S, A17], a18: SchemaField[S, A18])(const : (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7], arr(8).asInstanceOf[A8], arr(9).asInstanceOf[A9], arr(10).asInstanceOf[A10], arr(11).asInstanceOf[A11], arr(12).asInstanceOf[A12], arr(13).asInstanceOf[A13], arr(14).asInstanceOf[A14], arr(15).asInstanceOf[A15], arr(16).asInstanceOf[A16], arr(17).asInstanceOf[A17], arr(18).asInstanceOf[A18])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7], a8: SchemaField[S, A8], a9: SchemaField[S, A9], a10: SchemaField[S, A10], a11: SchemaField[S, A11], a12: SchemaField[S, A12], a13: SchemaField[S, A13], a14: SchemaField[S, A14], a15: SchemaField[S, A15], a16: SchemaField[S, A16], a17: SchemaField[S, A17], a18: SchemaField[S, A18], a19: SchemaField[S, A19])(const : (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7], arr(8).asInstanceOf[A8], arr(9).asInstanceOf[A9], arr(10).asInstanceOf[A10], arr(11).asInstanceOf[A11], arr(12).asInstanceOf[A12], arr(13).asInstanceOf[A13], arr(14).asInstanceOf[A14], arr(15).asInstanceOf[A15], arr(16).asInstanceOf[A16], arr(17).asInstanceOf[A17], arr(18).asInstanceOf[A18], arr(19).asInstanceOf[A19])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7], a8: SchemaField[S, A8], a9: SchemaField[S, A9], a10: SchemaField[S, A10], a11: SchemaField[S, A11], a12: SchemaField[S, A12], a13: SchemaField[S, A13], a14: SchemaField[S, A14], a15: SchemaField[S, A15], a16: SchemaField[S, A16], a17: SchemaField[S, A17], a18: SchemaField[S, A18], a19: SchemaField[S, A19], a20: SchemaField[S, A20])(const : (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7], arr(8).asInstanceOf[A8], arr(9).asInstanceOf[A9], arr(10).asInstanceOf[A10], arr(11).asInstanceOf[A11], arr(12).asInstanceOf[A12], arr(13).asInstanceOf[A13], arr(14).asInstanceOf[A14], arr(15).asInstanceOf[A15], arr(16).asInstanceOf[A16], arr(17).asInstanceOf[A17], arr(18).asInstanceOf[A18], arr(19).asInstanceOf[A19], arr(20).asInstanceOf[A20])) - def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21](a0: SchemaField[S, A0], a1: SchemaField[S, A1], a2: SchemaField[S, A2], a3: SchemaField[S, A3], a4: SchemaField[S, A4], a5: SchemaField[S, A5], a6: SchemaField[S, A6], a7: SchemaField[S, A7], a8: SchemaField[S, A8], a9: SchemaField[S, A9], a10: SchemaField[S, A10], a11: SchemaField[S, A11], a12: SchemaField[S, A12], a13: SchemaField[S, A13], a14: SchemaField[S, A14], a15: SchemaField[S, A15], a16: SchemaField[S, A16], a17: SchemaField[S, A17], a18: SchemaField[S, A18], a19: SchemaField[S, A19], a20: SchemaField[S, A20], a21: SchemaField[S, A21])(const : (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21), arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1], arr(2).asInstanceOf[A2], arr(3).asInstanceOf[A3], arr(4).asInstanceOf[A4], arr(5).asInstanceOf[A5], arr(6).asInstanceOf[A6], arr(7).asInstanceOf[A7], arr(8).asInstanceOf[A8], arr(9).asInstanceOf[A9], arr(10).asInstanceOf[A10], arr(11).asInstanceOf[A11], arr(12).asInstanceOf[A12], arr(13).asInstanceOf[A13], arr(14).asInstanceOf[A14], arr(15).asInstanceOf[A15], arr(16).asInstanceOf[A16], arr(17).asInstanceOf[A17], arr(18).asInstanceOf[A18], arr(19).asInstanceOf[A19], arr(20).asInstanceOf[A20], arr(21).asInstanceOf[A21])) - -} \ No newline at end of file diff --git a/modules/core/src/generated/kinds/polyFunctions.scala b/modules/core/src/generated/kinds/polyFunctions.scala new file mode 100644 index 000000000..407e8ed14 --- /dev/null +++ b/modules/core/src/generated/kinds/polyFunctions.scala @@ -0,0 +1,172 @@ +/* + * Copyright 2021-2022 Disney Streaming + * + * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://disneystreaming.github.io/TOST-1.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/////// THIS FILE WAS GENERATED AT BUILD TIME, AND CHECKED-IN FOR DISCOVERABILITY /////// + +package smithy4s +package kinds + +import smithy4s.capability._ + +trait PolyFunction[F[_], G[_]] { self => + def apply[A0](fa: F[A0]): G[A0] + + final def andThen[H[_]](other: PolyFunction[G, H]): PolyFunction[F, H] = + new PolyFunction[F, H] { + def apply[A0](fa: F[A0]): H[A0] = other(self(fa)) + } + + import Kind1._ + private[smithy4s] final def unsafeCacheBy[K]( + allPossibleInputs: Seq[Existential[F]], + getKey: Existential[F] => K + ): PolyFunction[F, G] = + new PolyFunction[F, G] { + private val map: Map[K, Any] = { + val builder = Map.newBuilder[K, Any] + allPossibleInputs.foreach(input => + builder += getKey(input) -> self + .apply(input.asInstanceOf[F[Any]]) + .asInstanceOf[Any] + ) + builder.result() + } + def apply[A0](input: F[A0]): G[A0] = + map(getKey(existential(input))).asInstanceOf[G[A0]] + } +} +object PolyFunction { + type From[F[_]] = { + type Algebra[G[_]] = PolyFunction[F, G] + } + + def identity[F[_]]: PolyFunction[F, F] = new PolyFunction[F, F] { + def apply[A0](input: F[A0]): F[A0] = input + } + + implicit def polyfunction_transformation[Alg[_[_]]: FunctorK, F[_], G[_]] + : Transformation[PolyFunction[F, G], Alg[F], Alg[G]] = + new Transformation[PolyFunction[F, G], Alg[F], Alg[G]] { + def apply(func: PolyFunction[F, G], algF: Alg[F]): Alg[G] = + FunctorK[Alg].mapK(algF, func) + } +} + +trait PolyFunction2[F[_, _], G[_, _]] { self => + def apply[A0, A1](fa: F[A0, A1]): G[A0, A1] + + final def andThen[H[_, _]](other: PolyFunction2[G, H]): PolyFunction2[F, H] = + new PolyFunction2[F, H] { + def apply[A0, A1](fa: F[A0, A1]): H[A0, A1] = other(self(fa)) + } + + import Kind2._ + private[smithy4s] final def unsafeCacheBy[K]( + allPossibleInputs: Seq[Existential[F]], + getKey: Existential[F] => K + ): PolyFunction2[F, G] = + new PolyFunction2[F, G] { + private val map: Map[K, Any] = { + val builder = Map.newBuilder[K, Any] + allPossibleInputs.foreach(input => + builder += getKey(input) -> self + .apply(input.asInstanceOf[F[Any, Any]]) + .asInstanceOf[Any] + ) + builder.result() + } + def apply[A0, A1](input: F[A0, A1]): G[A0, A1] = map( + getKey(existential(input)) + ).asInstanceOf[G[A0, A1]] + } +} +object PolyFunction2 { + type From[F[_, _]] = { + type Algebra[G[_, _]] = PolyFunction2[F, G] + } + + def identity[F[_, _]]: PolyFunction2[F, F] = new PolyFunction2[F, F] { + def apply[A0, A1](input: F[A0, A1]): F[A0, A1] = input + } + + implicit def polyfunction2_transformation[Alg[_[_, _]]: FunctorK2, F[_, _], G[ + _, + _ + ]]: Transformation[PolyFunction2[F, G], Alg[F], Alg[G]] = + new Transformation[PolyFunction2[F, G], Alg[F], Alg[G]] { + def apply(func: PolyFunction2[F, G], algF: Alg[F]): Alg[G] = + FunctorK2[Alg].mapK2(algF, func) + } +} + +trait PolyFunction5[F[_, _, _, _, _], G[_, _, _, _, _]] { self => + def apply[A0, A1, A2, A3, A4]( + fa: F[A0, A1, A2, A3, A4] + ): G[A0, A1, A2, A3, A4] + + final def andThen[H[_, _, _, _, _]]( + other: PolyFunction5[G, H] + ): PolyFunction5[F, H] = new PolyFunction5[F, H] { + def apply[A0, A1, A2, A3, A4]( + fa: F[A0, A1, A2, A3, A4] + ): H[A0, A1, A2, A3, A4] = other(self(fa)) + } + + import Kind5._ + private[smithy4s] final def unsafeCacheBy[K]( + allPossibleInputs: Seq[Existential[F]], + getKey: Existential[F] => K + ): PolyFunction5[F, G] = + new PolyFunction5[F, G] { + private val map: Map[K, Any] = { + val builder = Map.newBuilder[K, Any] + allPossibleInputs.foreach(input => + builder += getKey(input) -> self + .apply(input.asInstanceOf[F[Any, Any, Any, Any, Any]]) + .asInstanceOf[Any] + ) + builder.result() + } + def apply[A0, A1, A2, A3, A4]( + input: F[A0, A1, A2, A3, A4] + ): G[A0, A1, A2, A3, A4] = + map(getKey(existential(input))).asInstanceOf[G[A0, A1, A2, A3, A4]] + } +} +object PolyFunction5 { + type From[F[_, _, _, _, _]] = { + type Algebra[G[_, _, _, _, _]] = PolyFunction5[F, G] + } + + def identity[F[_, _, _, _, _]]: PolyFunction5[F, F] = + new PolyFunction5[F, F] { + def apply[A0, A1, A2, A3, A4]( + input: F[A0, A1, A2, A3, A4] + ): F[A0, A1, A2, A3, A4] = input + } + + implicit def polyfunction5_transformation[Alg[_[_, _, _, _, _]]: FunctorK5, F[ + _, + _, + _, + _, + _ + ], G[_, _, _, _, _]]: Transformation[PolyFunction5[F, G], Alg[F], Alg[G]] = + new Transformation[PolyFunction5[F, G], Alg[F], Alg[G]] { + def apply(func: PolyFunction5[F, G], algF: Alg[F]): Alg[G] = + FunctorK5[Alg].mapK5(algF, func) + } +} diff --git a/modules/core/src/generated/schema/PartiallyAppliedStruct.scala b/modules/core/src/generated/schema/PartiallyAppliedStruct.scala new file mode 100644 index 000000000..f4ab1dff7 --- /dev/null +++ b/modules/core/src/generated/schema/PartiallyAppliedStruct.scala @@ -0,0 +1,1192 @@ +/* + * Copyright 2021-2022 Disney Streaming + * + * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://disneystreaming.github.io/TOST-1.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/////// THIS FILE WAS GENERATED AT BUILD TIME, AND CHECKED-IN FOR DISCOVERABILITY /////// + +package smithy4s +package schema + +class PartiallyAppliedStruct[S] protected[schema] (placeholder: ShapeId) { + + def genericArity(fields: SchemaField[S, _]*)( + const: IndexedSeq[Any] => S + ): Schema[S] = + Schema.StructSchema(placeholder, Hints.empty, fields.toVector, const) + + def apply(fields: Vector[SchemaField[S, _]])( + const: IndexedSeq[Any] => S + ): Schema[S] = + Schema.StructSchema(placeholder, Hints.empty, fields, const) + + def apply[A0](a0: SchemaField[S, A0])(const: (A0) => S): Schema[S] = + Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0), + arr => const(arr(0).asInstanceOf[A0]) + ) + def apply[A0, A1](a0: SchemaField[S, A0], a1: SchemaField[S, A1])( + const: (A0, A1) => S + ): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0, a1), + arr => const(arr(0).asInstanceOf[A0], arr(1).asInstanceOf[A1]) + ) + def apply[A0, A1, A2]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2] + )(const: (A0, A1, A2) => S): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0, a1, a2), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2] + ) + ) + def apply[A0, A1, A2, A3]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3] + )(const: (A0, A1, A2, A3) => S): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0, a1, a2, a3), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3] + ) + ) + def apply[A0, A1, A2, A3, A4]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4] + )(const: (A0, A1, A2, A3, A4) => S): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0, a1, a2, a3, a4), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4] + ) + ) + def apply[A0, A1, A2, A3, A4, A5]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5] + )(const: (A0, A1, A2, A3, A4, A5) => S): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0, a1, a2, a3, a4, a5), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5] + ) + ) + def apply[A0, A1, A2, A3, A4, A5, A6]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6] + )(const: (A0, A1, A2, A3, A4, A5, A6) => S): Schema[S] = + Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0, a1, a2, a3, a4, a5, a6), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6] + ) + ) + def apply[A0, A1, A2, A3, A4, A5, A6, A7]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7] + )(const: (A0, A1, A2, A3, A4, A5, A6, A7) => S): Schema[S] = + Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0, a1, a2, a3, a4, a5, a6, a7), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7] + ) + ) + def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7], + a8: SchemaField[S, A8] + )(const: (A0, A1, A2, A3, A4, A5, A6, A7, A8) => S): Schema[S] = + Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7], + arr(8).asInstanceOf[A8] + ) + ) + def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7], + a8: SchemaField[S, A8], + a9: SchemaField[S, A9] + )(const: (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9) => S): Schema[S] = + Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7], + arr(8).asInstanceOf[A8], + arr(9).asInstanceOf[A9] + ) + ) + def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7], + a8: SchemaField[S, A8], + a9: SchemaField[S, A9], + a10: SchemaField[S, A10] + )(const: (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) => S): Schema[S] = + Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7], + arr(8).asInstanceOf[A8], + arr(9).asInstanceOf[A9], + arr(10).asInstanceOf[A10] + ) + ) + def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7], + a8: SchemaField[S, A8], + a9: SchemaField[S, A9], + a10: SchemaField[S, A10], + a11: SchemaField[S, A11] + )(const: (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) => S): Schema[S] = + Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7], + arr(8).asInstanceOf[A8], + arr(9).asInstanceOf[A9], + arr(10).asInstanceOf[A10], + arr(11).asInstanceOf[A11] + ) + ) + def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7], + a8: SchemaField[S, A8], + a9: SchemaField[S, A9], + a10: SchemaField[S, A10], + a11: SchemaField[S, A11], + a12: SchemaField[S, A12] + )( + const: (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) => S + ): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7], + arr(8).asInstanceOf[A8], + arr(9).asInstanceOf[A9], + arr(10).asInstanceOf[A10], + arr(11).asInstanceOf[A11], + arr(12).asInstanceOf[A12] + ) + ) + def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7], + a8: SchemaField[S, A8], + a9: SchemaField[S, A9], + a10: SchemaField[S, A10], + a11: SchemaField[S, A11], + a12: SchemaField[S, A12], + a13: SchemaField[S, A13] + )( + const: (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) => S + ): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7], + arr(8).asInstanceOf[A8], + arr(9).asInstanceOf[A9], + arr(10).asInstanceOf[A10], + arr(11).asInstanceOf[A11], + arr(12).asInstanceOf[A12], + arr(13).asInstanceOf[A13] + ) + ) + def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7], + a8: SchemaField[S, A8], + a9: SchemaField[S, A9], + a10: SchemaField[S, A10], + a11: SchemaField[S, A11], + a12: SchemaField[S, A12], + a13: SchemaField[S, A13], + a14: SchemaField[S, A14] + )( + const: ( + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14 + ) => S + ): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7], + arr(8).asInstanceOf[A8], + arr(9).asInstanceOf[A9], + arr(10).asInstanceOf[A10], + arr(11).asInstanceOf[A11], + arr(12).asInstanceOf[A12], + arr(13).asInstanceOf[A13], + arr(14).asInstanceOf[A14] + ) + ) + def apply[ + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15 + ]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7], + a8: SchemaField[S, A8], + a9: SchemaField[S, A9], + a10: SchemaField[S, A10], + a11: SchemaField[S, A11], + a12: SchemaField[S, A12], + a13: SchemaField[S, A13], + a14: SchemaField[S, A14], + a15: SchemaField[S, A15] + )( + const: ( + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15 + ) => S + ): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector( + a0, + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15 + ), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7], + arr(8).asInstanceOf[A8], + arr(9).asInstanceOf[A9], + arr(10).asInstanceOf[A10], + arr(11).asInstanceOf[A11], + arr(12).asInstanceOf[A12], + arr(13).asInstanceOf[A13], + arr(14).asInstanceOf[A14], + arr(15).asInstanceOf[A15] + ) + ) + def apply[ + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16 + ]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7], + a8: SchemaField[S, A8], + a9: SchemaField[S, A9], + a10: SchemaField[S, A10], + a11: SchemaField[S, A11], + a12: SchemaField[S, A12], + a13: SchemaField[S, A13], + a14: SchemaField[S, A14], + a15: SchemaField[S, A15], + a16: SchemaField[S, A16] + )( + const: ( + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16 + ) => S + ): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector( + a0, + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16 + ), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7], + arr(8).asInstanceOf[A8], + arr(9).asInstanceOf[A9], + arr(10).asInstanceOf[A10], + arr(11).asInstanceOf[A11], + arr(12).asInstanceOf[A12], + arr(13).asInstanceOf[A13], + arr(14).asInstanceOf[A14], + arr(15).asInstanceOf[A15], + arr(16).asInstanceOf[A16] + ) + ) + def apply[ + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17 + ]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7], + a8: SchemaField[S, A8], + a9: SchemaField[S, A9], + a10: SchemaField[S, A10], + a11: SchemaField[S, A11], + a12: SchemaField[S, A12], + a13: SchemaField[S, A13], + a14: SchemaField[S, A14], + a15: SchemaField[S, A15], + a16: SchemaField[S, A16], + a17: SchemaField[S, A17] + )( + const: ( + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17 + ) => S + ): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector( + a0, + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17 + ), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7], + arr(8).asInstanceOf[A8], + arr(9).asInstanceOf[A9], + arr(10).asInstanceOf[A10], + arr(11).asInstanceOf[A11], + arr(12).asInstanceOf[A12], + arr(13).asInstanceOf[A13], + arr(14).asInstanceOf[A14], + arr(15).asInstanceOf[A15], + arr(16).asInstanceOf[A16], + arr(17).asInstanceOf[A17] + ) + ) + def apply[ + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18 + ]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7], + a8: SchemaField[S, A8], + a9: SchemaField[S, A9], + a10: SchemaField[S, A10], + a11: SchemaField[S, A11], + a12: SchemaField[S, A12], + a13: SchemaField[S, A13], + a14: SchemaField[S, A14], + a15: SchemaField[S, A15], + a16: SchemaField[S, A16], + a17: SchemaField[S, A17], + a18: SchemaField[S, A18] + )( + const: ( + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18 + ) => S + ): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector( + a0, + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17, + a18 + ), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7], + arr(8).asInstanceOf[A8], + arr(9).asInstanceOf[A9], + arr(10).asInstanceOf[A10], + arr(11).asInstanceOf[A11], + arr(12).asInstanceOf[A12], + arr(13).asInstanceOf[A13], + arr(14).asInstanceOf[A14], + arr(15).asInstanceOf[A15], + arr(16).asInstanceOf[A16], + arr(17).asInstanceOf[A17], + arr(18).asInstanceOf[A18] + ) + ) + def apply[ + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19 + ]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7], + a8: SchemaField[S, A8], + a9: SchemaField[S, A9], + a10: SchemaField[S, A10], + a11: SchemaField[S, A11], + a12: SchemaField[S, A12], + a13: SchemaField[S, A13], + a14: SchemaField[S, A14], + a15: SchemaField[S, A15], + a16: SchemaField[S, A16], + a17: SchemaField[S, A17], + a18: SchemaField[S, A18], + a19: SchemaField[S, A19] + )( + const: ( + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19 + ) => S + ): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector( + a0, + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17, + a18, + a19 + ), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7], + arr(8).asInstanceOf[A8], + arr(9).asInstanceOf[A9], + arr(10).asInstanceOf[A10], + arr(11).asInstanceOf[A11], + arr(12).asInstanceOf[A12], + arr(13).asInstanceOf[A13], + arr(14).asInstanceOf[A14], + arr(15).asInstanceOf[A15], + arr(16).asInstanceOf[A16], + arr(17).asInstanceOf[A17], + arr(18).asInstanceOf[A18], + arr(19).asInstanceOf[A19] + ) + ) + def apply[ + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20 + ]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7], + a8: SchemaField[S, A8], + a9: SchemaField[S, A9], + a10: SchemaField[S, A10], + a11: SchemaField[S, A11], + a12: SchemaField[S, A12], + a13: SchemaField[S, A13], + a14: SchemaField[S, A14], + a15: SchemaField[S, A15], + a16: SchemaField[S, A16], + a17: SchemaField[S, A17], + a18: SchemaField[S, A18], + a19: SchemaField[S, A19], + a20: SchemaField[S, A20] + )( + const: ( + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20 + ) => S + ): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector( + a0, + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17, + a18, + a19, + a20 + ), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7], + arr(8).asInstanceOf[A8], + arr(9).asInstanceOf[A9], + arr(10).asInstanceOf[A10], + arr(11).asInstanceOf[A11], + arr(12).asInstanceOf[A12], + arr(13).asInstanceOf[A13], + arr(14).asInstanceOf[A14], + arr(15).asInstanceOf[A15], + arr(16).asInstanceOf[A16], + arr(17).asInstanceOf[A17], + arr(18).asInstanceOf[A18], + arr(19).asInstanceOf[A19], + arr(20).asInstanceOf[A20] + ) + ) + def apply[ + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21 + ]( + a0: SchemaField[S, A0], + a1: SchemaField[S, A1], + a2: SchemaField[S, A2], + a3: SchemaField[S, A3], + a4: SchemaField[S, A4], + a5: SchemaField[S, A5], + a6: SchemaField[S, A6], + a7: SchemaField[S, A7], + a8: SchemaField[S, A8], + a9: SchemaField[S, A9], + a10: SchemaField[S, A10], + a11: SchemaField[S, A11], + a12: SchemaField[S, A12], + a13: SchemaField[S, A13], + a14: SchemaField[S, A14], + a15: SchemaField[S, A15], + a16: SchemaField[S, A16], + a17: SchemaField[S, A17], + a18: SchemaField[S, A18], + a19: SchemaField[S, A19], + a20: SchemaField[S, A20], + a21: SchemaField[S, A21] + )( + const: ( + A0, + A1, + A2, + A3, + A4, + A5, + A6, + A7, + A8, + A9, + A10, + A11, + A12, + A13, + A14, + A15, + A16, + A17, + A18, + A19, + A20, + A21 + ) => S + ): Schema[S] = Schema.StructSchema[S]( + placeholder, + Hints.empty, + Vector( + a0, + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + a17, + a18, + a19, + a20, + a21 + ), + arr => + const( + arr(0).asInstanceOf[A0], + arr(1).asInstanceOf[A1], + arr(2).asInstanceOf[A2], + arr(3).asInstanceOf[A3], + arr(4).asInstanceOf[A4], + arr(5).asInstanceOf[A5], + arr(6).asInstanceOf[A6], + arr(7).asInstanceOf[A7], + arr(8).asInstanceOf[A8], + arr(9).asInstanceOf[A9], + arr(10).asInstanceOf[A10], + arr(11).asInstanceOf[A11], + arr(12).asInstanceOf[A12], + arr(13).asInstanceOf[A13], + arr(14).asInstanceOf[A14], + arr(15).asInstanceOf[A15], + arr(16).asInstanceOf[A16], + arr(17).asInstanceOf[A17], + arr(18).asInstanceOf[A18], + arr(19).asInstanceOf[A19], + arr(20).asInstanceOf[A20], + arr(21).asInstanceOf[A21] + ) + ) + +} diff --git a/modules/core/src/smithy4s/PolyFunction.scala b/modules/core/src/smithy4s/PolyFunction.scala deleted file mode 100644 index 15dc6bedf..000000000 --- a/modules/core/src/smithy4s/PolyFunction.scala +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2021-2022 Disney Streaming - * - * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://disneystreaming.github.io/TOST-1.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smithy4s - -import smithy4s.internals.maps.MMap - -/** - * Natural transformation, turning a polymorphic type into another, - * whilst keeping the type parameter intact. - */ -trait PolyFunction[F[_], G[_]] { self => - def apply[A](fa: F[A]): G[A] - - final def andThen[H[_]](other: PolyFunction[G, H]): PolyFunction[F, H] = - new PolyFunction[F, H] { - def apply[A](fa: F[A]): H[A] = other(self(fa)) - } - - final def mapK[H[_]](fk: PolyFunction[G, H]): PolyFunction[F, H] = andThen(fk) - - /** - * Creates a memoised version of this function. - * - * Unsafe because it creates mutable state, which is a - * non-referentially-transparent action (aka a side-effect). - */ - final def unsafeMemoise: PolyFunction[F, G] = - new PolyFunction[F, G] { - private val map: MMap[Any, Any] = MMap.empty - - def apply[A](fa: F[A]): G[A] = { - map - .getOrElseUpdate(fa, self(fa)) - .asInstanceOf[G[A]] - } - - } - - /** - * Pre-computes the polyfunction by applying it on a vector - * of possible inputs. - * - * Unsafe because calling the resulting polyfunction with an input that wasn't cached - * will result in an exception. - */ - final def unsafeCache( - allPossibleInputs: Vector[Existential[F]] - ): PolyFunction[F, G] = - new PolyFunction[F, G] { - private val map: Map[Any, Any] = { - val builder = Map.newBuilder[Any, Any] - allPossibleInputs.foreach(input => - builder += input -> self - .apply(input.asInstanceOf[F[Any]]) - .asInstanceOf[Any] - ) - builder.result() - } - def apply[A](input: F[A]): G[A] = { - map(input).asInstanceOf[G[A]] - } - } - - private[smithy4s] final def unsafeCacheBy[K]( - allPossibleInputs: Vector[Existential[F]], - getKey: Existential[F] => K - ): PolyFunction[F, G] = - new PolyFunction[F, G] { - private val map: Map[K, Any] = { - val builder = Map.newBuilder[K, Any] - allPossibleInputs.foreach(input => - builder += getKey(input) -> self - .apply(input.asInstanceOf[F[Any]]) - .asInstanceOf[Any] - ) - builder.result() - } - def apply[A](input: F[A]): G[A] = { - map(getKey(Existential.wrap(input))).asInstanceOf[G[A]] - } - } -} diff --git a/modules/core/src/smithy4s/Service.scala b/modules/core/src/smithy4s/Service.scala index 367f382db..3b3c53eb2 100644 --- a/modules/core/src/smithy4s/Service.scala +++ b/modules/core/src/smithy4s/Service.scala @@ -16,13 +16,15 @@ package smithy4s +import kinds._ + //format: off /** * Generic representation of a service, as a list of "endpoints" (mapping to smithy operations). * * This abstraction lets us retrieve all information necessary to the generic implementation of * protocols, as well as transform implementations of finally-encoded interfaces into interpreters - * (natural transformations) that operate on initially-encoded GADTs. + * (polymorphic functions) that operate on initially-encoded GADTs. * * @tparam Alg : a finally-encoded interface (commonly called algebra) that works * against an abstract "effect" that takes 5 type parameters: @@ -32,32 +34,36 @@ package smithy4s * around makes it drastically easier to implement logic generically, without involving * metaprogramming. */ -trait Service[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _]] extends Transformable[Alg] with Service.Provider[Alg, Op] { +trait Service[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _]] extends FunctorK5[Alg] with Service.Provider[Alg, Op] { implicit val serviceInstance: Service[Alg, Op] = this val service = this def endpoints: List[Endpoint[Op, _, _, _, _, _]] def endpoint[I, E, O, SI, SO](op: Op[I, E, O, SI, SO]): (I, Endpoint[Op, I, E, O, SI, SO]) - val opToEndpoint : Transformation[Op, Endpoint[Op, *, *, *, *,*]] = new Transformation[Op, Endpoint[Op, *, *, *, *,*]]{ - def apply[I, E, O, SI, SO](op: Op[I,E,O,SI,SO]): Endpoint[Op,I,E,O,SI,SO] = endpoint(op)._2 - } - def version: String - def hints: Hints + def reified: Alg[Op] + def fromPolyFunction[P[_, _, _, _, _]](function: PolyFunction5[Op, P]): Alg[P] + def toPolyFunction[P[_, _, _, _, _]](algebra: Alg[P]): PolyFunction5[Op, P] - def transform[P[_, _, _, _, _]](transformation: Transformation[Op, P]): Alg[P] - - def asTransformation[P[_, _, _, _, _]](impl: Alg[P]): Transformation[Op, P] - - // Apply a transformation that is aware of the endpoint - def transformWithEndpoint[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: Alg[P], transformation: Transformation.ZippedWithEndpoint[P, Op, P1]) : Alg[P1] = { - this.transform(asTransformation(alg).zip(opToEndpoint).andThen(transformation)) + final val opToEndpoint : PolyFunction5[Op, Endpoint[Op, *, *, *, *, *]] = new PolyFunction5[Op, Endpoint[Op, *, *, *, *, *]]{ + def apply[I, E, O, SI, SO](op: Op[I,E,O,SI,SO]): Endpoint[Op,I,E,O,SI,SO] = endpoint(op)._2 } + } object Service { trait Provider[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _]] extends HasId { def service: Service[Alg, Op] } + + /** + * A Service the algebra of which is a PolyFunction + */ + trait Reflective[Op[_, _, _, _, _]] extends Service[PolyFunction5.From[Op]#Algebra, Op] { + final def reified: PolyFunction5[Op, Op] = PolyFunction5.identity + final def fromPolyFunction[P[_, _, _, _, _]](function: PolyFunction5[Op, P]): PolyFunction5[Op, P] = function + final def toPolyFunction[P[_, _, _, _, _]](algebra: PolyFunction5[Op, P]): PolyFunction5[Op, P] = algebra + final def mapK5[F[_, _, _, _, _], G[_, _, _, _, _]](algebra: PolyFunction5[Op, F], function: PolyFunction5[F, G]) : PolyFunction5[Op, G] = algebra.andThen(function) + } } diff --git a/modules/core/src/smithy4s/Transformable.scala b/modules/core/src/smithy4s/Transformable.scala deleted file mode 100644 index 569ce97d4..000000000 --- a/modules/core/src/smithy4s/Transformable.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2021-2022 Disney Streaming - * - * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://disneystreaming.github.io/TOST-1.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smithy4s - -/** - * Allows to transform the effect an algebra works against. - */ -trait Transformable[Alg[_[_, _, _, _, _]]] { - - // format: off - def transform[F[_, _, _, _, _], G[_, _, _, _, _]](alg: Alg[F], transformation: Transformation[F, G]): Alg[G] - -} diff --git a/modules/core/src/smithy4s/Transformation.scala b/modules/core/src/smithy4s/Transformation.scala deleted file mode 100644 index 7e2e78759..000000000 --- a/modules/core/src/smithy4s/Transformation.scala +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2021-2022 Disney Streaming - * - * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://disneystreaming.github.io/TOST-1.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package smithy4s - -import Transformation.Zip - -/** - * Natural transformation allowing to change the outer type - * that final interfaces work against. - */ -trait Transformation[F[_, _, _, _, _], G[_, _, _, _, _]] { self => - def apply[I, E, O, SI, SO](fa: F[I, E, O, SI, SO]): G[I, E, O, SI, SO] - - def zip[G2[_, _, _, _, _]]( - other: Transformation[F, G2] - ): Transformation[F, Zip[G, G2, *, *, *, *, *]] = - new Transformation[F, Zip[G, G2, *, *, *, *, *]] { - def apply[I, E, O, SI, SO]( - fa: F[I, E, O, SI, SO] - ): Zip[G, G2, I, E, O, SI, SO] = - Zip(self(fa), other(fa)) - } - - def andThen[H[_, _, _, _, _]]( - other: Transformation[G, H] - ): Transformation[F, H] = new Transformation[F, H] { - def apply[I, E, O, SI, SO](fa: F[I, E, O, SI, SO]): H[I, E, O, SI, SO] = - other(self(fa)) - } - - /** - * Pre-computes the transormation by applying it on an iterable of all possible inputs. - * - * Unsafe because calling the resulting transformation with an value that wasn't precomputed - * will result in an exception. - * - * See https://stackoverflow.com/questions/67750145/how-to-implement-types-like-mapk-in-scala-3-dotty - */ - def precompute( - allPossibleInputs: Iterable[Kind5.Existential[F]] - ): Transformation[F, G] = - new Transformation[F, G] { - private val map: Map[Any, Any] = { - val builder = Map.newBuilder[Any, Any] - allPossibleInputs.foreach(input => - builder += input -> self - .apply(input.asInstanceOf[F[Any, Any, Any, Any, Any]]) - .asInstanceOf[Any] - ) - builder.result() - } - def apply[I, E, O, SI, SO]( - input: F[I, E, O, SI, SO] - ): G[I, E, O, SI, SO] = { - map(input).asInstanceOf[G[I, E, O, SI, SO]] - } - } - -} - -object Transformation { - - def identity[F[_, _, _, _, _]]: Transformation[F, F] = - new Transformation[F, F] { - def apply[I, E, O, SI, SO](fa: F[I, E, O, SI, SO]): F[I, E, O, SI, SO] = - fa - } - - // format: off - case class Zip[F1[_, _, _, _, _], F2[_, _, _, _, _], I, E, O, SI, SO]( - _1: F1[I, E, O, SI, SO], - _2: F2[I, E, O, SI, SO] - ) - - object Zip { - type Of[F1[_, _, _, _, _], F2[_, _, _, _, _]] = { - type λ[I, E, O, SI, SO] = Zip[F1, F2, I, E, O, SI, SO] - } - } - - type Zipped[F1[_, _, _, _, _], F2[_, _, _, _, _], G[_, _, _, _, _]] = - Transformation[Zip.Of[F1, F2]#λ, G] - - type ZippedWithEndpoint[F[_, _, _, _, _], Op[_,_,_,_,_], G[_,_,_,_,_]] = - Zipped[F, Endpoint[Op, *, *, *, *, *], G] - // format: on - -} diff --git a/modules/core/src/smithy4s/capability/Transformation.scala b/modules/core/src/smithy4s/capability/Transformation.scala new file mode 100644 index 000000000..23280c32d --- /dev/null +++ b/modules/core/src/smithy4s/capability/Transformation.scala @@ -0,0 +1,37 @@ +package smithy4s +package capability + +import kinds._ + +/** + * Heterogenous function construct, allows to abstract over various kinds of functions + * whilst providing an homogenous user experience without the user having to + * manually lift functions from one kind to the other. + * + * Used to reduce the noise of transformations + */ +trait Transformation[Func, Input, Output] { + def apply(f: Func, input: Input): Output +} + +object Transformation { + + // format: off + implicit def functorK5_poly1_transformation[Alg[_[_, _, _, _, _]]: FunctorK5, F[_], G[_]]: Transformation[PolyFunction[F, G], FunctorAlgebra[Alg, F], FunctorAlgebra[Alg, G]] = + new Transformation[PolyFunction[F, G], FunctorAlgebra[Alg, F], FunctorAlgebra[Alg, G]]{ + def apply(func: PolyFunction[F, G], algF: FunctorAlgebra[Alg, F]) : FunctorAlgebra[Alg, G] = FunctorK5[Alg].mapK5[Kind1[F]#toKind5, Kind1[G]#toKind5](algF, toPolyFunction5(func)) + } + + implicit def functorK5_poly2_transformation[Alg[_[_, _, _, _, _]]: FunctorK5, F[_,_], G[_, _]]: Transformation[PolyFunction2[F, G], BiFunctorAlgebra[Alg, F], BiFunctorAlgebra[Alg, G]] = + new Transformation[PolyFunction2[F, G], BiFunctorAlgebra[Alg, F], BiFunctorAlgebra[Alg, G]]{ + def apply(func: PolyFunction2[F, G], algF: BiFunctorAlgebra[Alg, F]) : BiFunctorAlgebra[Alg, G] = FunctorK5[Alg].mapK5[Kind2[F]#toKind5, Kind2[G]#toKind5](algF, toPolyFunction5(func)) + } + + + class PartiallyApplied[Input](input: Input) { + def apply[Func, Output](func: Func)(implicit + transform: Transformation[Func, Input, Output] + ) = transform(func, input) + } + +} diff --git a/modules/core/src/smithy4s/http/Metadata.scala b/modules/core/src/smithy4s/http/Metadata.scala index d85f6807e..2f05ee8f1 100644 --- a/modules/core/src/smithy4s/http/Metadata.scala +++ b/modules/core/src/smithy4s/http/Metadata.scala @@ -281,12 +281,7 @@ object Metadata { @deprecated("kept for bincompat in 0.16.x") def deriveEncoderFromStaticSchema[A](implicit schema: Schema[A] - ): Encoder[A] = encoderCache(schema) - - private val encoderCache = - new PolyFunction[smithy4s.Schema, Encoder] { - def apply[A](fa: smithy4s.Schema[A]): Encoder[A] = fromSchema(fa) - }.unsafeMemoise + ): Encoder[A] = fromSchema(schema) } diff --git a/modules/core/src/smithy4s/internals/SchemaDescriptionDetailed.scala b/modules/core/src/smithy4s/internals/SchemaDescriptionDetailed.scala index 0907072ec..038954fe4 100644 --- a/modules/core/src/smithy4s/internals/SchemaDescriptionDetailed.scala +++ b/modules/core/src/smithy4s/internals/SchemaDescriptionDetailed.scala @@ -160,7 +160,7 @@ private[internals] object SchemaDescriptionDetailedImpl } val conversion: SchemaDescriptionDetailedImpl ~> SchemaDescription = - new PolyFunction[SchemaDescriptionDetailedImpl, SchemaDescription] { + new (SchemaDescriptionDetailedImpl ~> SchemaDescription) { def apply[A]( fa: SchemaDescriptionDetailedImpl[A] ): SchemaDescription[A] = fa(Set.empty)._2 diff --git a/modules/core/src/smithy4s/internals/package.scala b/modules/core/src/smithy4s/internals/package.scala index 9736f55d4..f2d8892ad 100644 --- a/modules/core/src/smithy4s/internals/package.scala +++ b/modules/core/src/smithy4s/internals/package.scala @@ -19,5 +19,7 @@ package smithy4s package object internals { type SchemaDescription[A] = String val SchemaDescriptionDetailed: Schema ~> SchemaDescription = - SchemaDescriptionDetailedImpl.mapK(SchemaDescriptionDetailedImpl.conversion) + SchemaDescriptionDetailedImpl.andThen( + SchemaDescriptionDetailedImpl.conversion + ) } diff --git a/modules/core/src/smithy4s/kinds/toPolyFunction5.scala b/modules/core/src/smithy4s/kinds/toPolyFunction5.scala new file mode 100644 index 000000000..cd033847a --- /dev/null +++ b/modules/core/src/smithy4s/kinds/toPolyFunction5.scala @@ -0,0 +1,25 @@ +package smithy4s.kinds + +object toPolyFunction5 { + + /** + * Lifts a PolyFunction to a PolyFunction5 + */ + def apply[F[_], G[_]]( + f: PolyFunction[F, G] + ): PolyFunction5[Kind1[F]#toKind5, Kind1[G]#toKind5] = + new PolyFunction5[Kind1[F]#toKind5, Kind1[G]#toKind5] { + def apply[I, E, O, SI, SO](fa: F[O]): G[O] = f(fa) + } + + /** + * Lifts a PolyFunction2 to a PolyFunction5 + */ + def apply[F[_, _], G[_, _]]( + f: PolyFunction2[F, G] + ): PolyFunction5[Kind2[F]#toKind5, Kind2[G]#toKind5] = + new PolyFunction5[Kind2[F]#toKind5, Kind2[G]#toKind5] { + def apply[I, E, O, SI, SO](fa: F[E, O]): G[E, O] = f(fa) + } + +} diff --git a/modules/core/src/smithy4s/package.scala b/modules/core/src/smithy4s/package.scala index fee99d70c..108c4056c 100644 --- a/modules/core/src/smithy4s/package.scala +++ b/modules/core/src/smithy4s/package.scala @@ -14,20 +14,16 @@ * limitations under the License. */ -package object smithy4s extends TypeAliases with ExistentialsPlatformCompat { +package object smithy4s { - type ~>[F[_], G[_]] = PolyFunction[F, G] type Hint = Hints.Binding type Schema[A] = schema.Schema[A] val Schema: schema.Schema.type = schema.Schema - type Wrapped[F[_], G[_], A] = F[G[A]] - val errorTypeHeader = "X-Error-Type" + type PolyFunction[F[_], G[_]] = kinds.PolyFunction[F, G] + type ~>[F[_], G[_]] = kinds.PolyFunction[F, G] - // Allows to "inject" F[_] types in places that require F[_,_,_,_,_] - type GenLift[F[_]] = { - type λ[I, E, O, SI, SO] = F[O] - } + val errorTypeHeader = "X-Error-Type" def checkProtocol[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _]]( service: Service[Alg, Op], diff --git a/modules/core/src/smithy4s/schema/Alt.scala b/modules/core/src/smithy4s/schema/Alt.scala index 29fb46f91..3d14296f7 100644 --- a/modules/core/src/smithy4s/schema/Alt.scala +++ b/modules/core/src/smithy4s/schema/Alt.scala @@ -18,6 +18,7 @@ package smithy4s package schema import smithy4s.capability.EncoderK +import kinds._ import scala.annotation.nowarn /** @@ -92,8 +93,8 @@ object Alt { val precompiledAlts = precompile.toPolyFunction .unsafeCacheBy[String]( - alts.map(smithy4s.Existential.wrap(_)), - (alt: Existential[Alt[F, U, *]]) => + alts.map(Kind1.existential(_)), + (alt: Kind1.Existential[Alt[F, U, *]]) => alt.asInstanceOf[Alt[F, U, _]].label ) diff --git a/modules/core/test/src/smithy4s/TransformationSmokeSpec.scala b/modules/core/test/src/smithy4s/TransformationSmokeSpec.scala new file mode 100644 index 000000000..779703f0b --- /dev/null +++ b/modules/core/test/src/smithy4s/TransformationSmokeSpec.scala @@ -0,0 +1,42 @@ +/* + * Copyright 2021-2022 Disney Streaming + * + * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://disneystreaming.github.io/TOST-1.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package smithy4s + +import smithy4s.example._ + +import munit._ +import scala.util.Try +class TransformationSmokeSpec() extends FunSuite { + + test("transform method can be called with poly functions") { + object stub extends Weather[Option] { + def getCurrentTime(): Option[GetCurrentTimeOutput] = None + } + + case object Empty extends Throwable + + // Not ascribing the type to get a + val transformed = stub.transform(new PolyFunction[Option, Try] { + def apply[A](fa: Option[A]): Try[A] = fa match { + case Some(value) => scala.util.Success(value) + case None => scala.util.Failure(Empty) + } + }) + expect(transformed.getCurrentTime().isFailure) + } + +} diff --git a/modules/decline/src/Smithy4sCli.scala b/modules/decline/src/Smithy4sCli.scala index b3bfd1f11..192176e24 100644 --- a/modules/decline/src/Smithy4sCli.scala +++ b/modules/decline/src/Smithy4sCli.scala @@ -25,16 +25,16 @@ import smithy.api.Documentation import smithy.api.ExternalDocumentation import smithy.api.Http import smithy4s.Endpoint -import smithy4s.GenLift import smithy4s.Monadic import smithy4s.Service import smithy4s.decline.core._ import smithy4s.decline.util.PrinterApi import smithy4s.http.HttpEndpoint +import smithy4s.kinds._ import commons._ final case class Entrypoint[Alg[_[_, _, _, _, _]], F[_]]( - interpreter: Monadic[Alg, F], + interpreter: FunctorAlgebra[Alg, F], printerApi: PrinterApi[F] ) @@ -103,7 +103,7 @@ class Smithy4sCli[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _], F[_]: MonadThrow]( val printers = entrypoint.printerApi val printer = printers.printer(endpoint) val FO = printer.printInput(input) *> - service.asTransformation[GenLift[F]#λ](entrypoint.interpreter)( + service.toPolyFunction[Kind1[F]#toKind5](entrypoint.interpreter)( endpoint.wrap(input) ) @@ -137,7 +137,7 @@ object Smithy4sCli { def standalone[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _], F[ _ ]: Console: MonadThrow]( - impl: Opts[smithy4s.Monadic[Alg, F]] + impl: Opts[FunctorAlgebra[Alg, F]] )(implicit service: Service[Alg, Op]) = { new Smithy4sCli[Alg, Op, F]( ( diff --git a/modules/dynamic/src/smithy4s/dynamic/internals/DynamicService.scala b/modules/dynamic/src/smithy4s/dynamic/internals/DynamicService.scala index 26bce9cfa..23e5a097f 100644 --- a/modules/dynamic/src/smithy4s/dynamic/internals/DynamicService.scala +++ b/modules/dynamic/src/smithy4s/dynamic/internals/DynamicService.scala @@ -18,23 +18,20 @@ package smithy4s package dynamic package internals +import smithy4s.kinds.PolyFunction5 + private[internals] case class DynamicService( id: ShapeId, version: String, endpoints: List[DynamicEndpoint], hints: Hints -) extends Service[DynamicAlg, DynamicOp] +) extends Service.Reflective[DynamicOp] with DynamicSchemaIndex.ServiceWrapper { - type Alg[P[_, _, _, _, _]] = DynamicAlg[P] + type Alg[P[_, _, _, _, _]] = PolyFunction5.From[DynamicOp]#Algebra[P] type Op[I, E, O, SI, SO] = DynamicOp[I, E, O, SI, SO] override val service: Service[Alg, Op] = this - def transform[F[_, _, _, _, _], G[_, _, _, _, _]]( - alg: DynamicAlg[F], - transformation: Transformation[F, G] - ): DynamicAlg[G] = alg.andThen(transformation) - private lazy val endpointMap : Map[ShapeId, Endpoint[DynamicOp, _, _, _, _, _]] = endpoints.map(ep => ep.id -> ep).toMap @@ -49,11 +46,4 @@ private[internals] case class DynamicService( (input, endpoint) } - def transform[P[_, _, _, _, _]]( - transformation: Transformation[DynamicOp, P] - ): DynamicAlg[P] = transformation - - def asTransformation[P[_, _, _, _, _]]( - impl: DynamicAlg[P] - ): Transformation[DynamicOp, P] = impl } diff --git a/modules/dynamic/src/smithy4s/dynamic/internals/package.scala b/modules/dynamic/src/smithy4s/dynamic/internals/package.scala index 6c13c5636..e2a53790a 100644 --- a/modules/dynamic/src/smithy4s/dynamic/internals/package.scala +++ b/modules/dynamic/src/smithy4s/dynamic/internals/package.scala @@ -22,7 +22,4 @@ package object internals { private[internals] type DynStruct = Array[DynData] private[internals] type DynAlt = (Int, DynData) - private[internals] type DynamicAlg[F[_, _, _, _, _]] = - smithy4s.Transformation[DynamicOp, F] - } diff --git a/modules/example/src/smithy4s/example/BrandService.scala b/modules/example/src/smithy4s/example/BrandService.scala index b9e6de62b..8a4bb25d2 100644 --- a/modules/example/src/smithy4s/example/BrandService.scala +++ b/modules/example/src/smithy4s/example/BrandService.scala @@ -2,11 +2,12 @@ package smithy4s.example import smithy4s.Schema import smithy4s.schema.Schema.unit -import smithy4s.Transformation -import smithy4s.Monadic +import smithy4s.kinds.PolyFunction5 import smithy4s.Service import smithy4s.Hints import smithy4s.StreamingSchema +import smithy4s.kinds.FunctorAlgebra +import smithy4s.capability.Transformation import smithy4s.ShapeId import smithy4s.Endpoint @@ -15,15 +16,12 @@ trait BrandServiceGen[F[_, _, _, _, _]] { def addBrands(brands: Option[List[String]] = None) : F[AddBrandsInput, Nothing, Unit, Nothing, Nothing] - def transform[G[_, _, _, _, _]](transformation : Transformation[F, G]) : BrandServiceGen[G] = new Transformed(transformation) - class Transformed[G[_, _, _, _, _]](transformation : Transformation[F, G]) extends BrandServiceGen[G] { - def addBrands(brands: Option[List[String]] = None) = transformation[AddBrandsInput, Nothing, Unit, Nothing, Nothing](self.addBrands(brands)) - } + def transform : Transformation.PartiallyApplied[BrandServiceGen[F]] = new Transformation.PartiallyApplied[BrandServiceGen[F]](this) } object BrandServiceGen extends Service[BrandServiceGen, BrandServiceOperation] { - def apply[F[_]](implicit F: Monadic[BrandServiceGen, F]): F.type = F + def apply[F[_]](implicit F: FunctorAlgebra[BrandServiceGen, F]): F.type = F val id: ShapeId = ShapeId("smithy4s.example", "BrandService") @@ -43,11 +41,14 @@ object BrandServiceGen extends Service[BrandServiceGen, BrandServiceOperation] { def addBrands(brands: Option[List[String]] = None) = AddBrands(AddBrandsInput(brands)) } - def transform[P[_, _, _, _, _]](transformation: Transformation[BrandServiceOperation, P]): BrandServiceGen[P] = reified.transform(transformation) + def mapK5[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: BrandServiceGen[P], f: PolyFunction5[P, P1]): BrandServiceGen[P1] = new Transformed(alg, f) - def transform[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: BrandServiceGen[P], transformation: Transformation[P, P1]): BrandServiceGen[P1] = alg.transform(transformation) + def fromPolyFunction[P[_, _, _, _, _]](f: PolyFunction5[BrandServiceOperation, P]): BrandServiceGen[P] = new Transformed(reified, f) + class Transformed[P[_, _, _, _, _], P1[_ ,_ ,_ ,_ ,_]](alg: BrandServiceGen[P], f : PolyFunction5[P, P1]) extends BrandServiceGen[P1] { + def addBrands(brands: Option[List[String]] = None) = f[AddBrandsInput, Nothing, Unit, Nothing, Nothing](alg.addBrands(brands)) + } - def asTransformation[P[_, _, _, _, _]](impl : BrandServiceGen[P]): Transformation[BrandServiceOperation, P] = new Transformation[BrandServiceOperation, P] { + def toPolyFunction[P[_, _, _, _, _]](impl : BrandServiceGen[P]): PolyFunction5[BrandServiceOperation, P] = new PolyFunction5[BrandServiceOperation, P] { def apply[I, E, O, SI, SO](op : BrandServiceOperation[I, E, O, SI, SO]) : P[I, E, O, SI, SO] = op match { case AddBrands(AddBrandsInput(brands)) => impl.addBrands(brands) } diff --git a/modules/example/src/smithy4s/example/FooService.scala b/modules/example/src/smithy4s/example/FooService.scala index 7b32088f8..66fb5cfee 100644 --- a/modules/example/src/smithy4s/example/FooService.scala +++ b/modules/example/src/smithy4s/example/FooService.scala @@ -2,11 +2,12 @@ package smithy4s.example import smithy4s.Schema import smithy4s.schema.Schema.unit -import smithy4s.Transformation -import smithy4s.Monadic +import smithy4s.kinds.PolyFunction5 import smithy4s.Service import smithy4s.Hints import smithy4s.StreamingSchema +import smithy4s.kinds.FunctorAlgebra +import smithy4s.capability.Transformation import smithy4s.ShapeId import smithy4s.Endpoint @@ -15,15 +16,12 @@ trait FooServiceGen[F[_, _, _, _, _]] { def getFoo() : F[Unit, Nothing, GetFooOutput, Nothing, Nothing] - def transform[G[_, _, _, _, _]](transformation : Transformation[F, G]) : FooServiceGen[G] = new Transformed(transformation) - class Transformed[G[_, _, _, _, _]](transformation : Transformation[F, G]) extends FooServiceGen[G] { - def getFoo() = transformation[Unit, Nothing, GetFooOutput, Nothing, Nothing](self.getFoo()) - } + def transform : Transformation.PartiallyApplied[FooServiceGen[F]] = new Transformation.PartiallyApplied[FooServiceGen[F]](this) } object FooServiceGen extends Service[FooServiceGen, FooServiceOperation] { - def apply[F[_]](implicit F: Monadic[FooServiceGen, F]): F.type = F + def apply[F[_]](implicit F: FunctorAlgebra[FooServiceGen, F]): F.type = F val id: ShapeId = ShapeId("smithy4s.example", "FooService") @@ -43,11 +41,14 @@ object FooServiceGen extends Service[FooServiceGen, FooServiceOperation] { def getFoo() = GetFoo() } - def transform[P[_, _, _, _, _]](transformation: Transformation[FooServiceOperation, P]): FooServiceGen[P] = reified.transform(transformation) + def mapK5[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: FooServiceGen[P], f: PolyFunction5[P, P1]): FooServiceGen[P1] = new Transformed(alg, f) - def transform[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: FooServiceGen[P], transformation: Transformation[P, P1]): FooServiceGen[P1] = alg.transform(transformation) + def fromPolyFunction[P[_, _, _, _, _]](f: PolyFunction5[FooServiceOperation, P]): FooServiceGen[P] = new Transformed(reified, f) + class Transformed[P[_, _, _, _, _], P1[_ ,_ ,_ ,_ ,_]](alg: FooServiceGen[P], f : PolyFunction5[P, P1]) extends FooServiceGen[P1] { + def getFoo() = f[Unit, Nothing, GetFooOutput, Nothing, Nothing](alg.getFoo()) + } - def asTransformation[P[_, _, _, _, _]](impl : FooServiceGen[P]): Transformation[FooServiceOperation, P] = new Transformation[FooServiceOperation, P] { + def toPolyFunction[P[_, _, _, _, _]](impl : FooServiceGen[P]): PolyFunction5[FooServiceOperation, P] = new PolyFunction5[FooServiceOperation, P] { def apply[I, E, O, SI, SO](op : FooServiceOperation[I, E, O, SI, SO]) : P[I, E, O, SI, SO] = op match { case GetFoo() => impl.getFoo() } diff --git a/modules/example/src/smithy4s/example/NameCollision.scala b/modules/example/src/smithy4s/example/NameCollision.scala index 0360520d5..7dd75dc6d 100644 --- a/modules/example/src/smithy4s/example/NameCollision.scala +++ b/modules/example/src/smithy4s/example/NameCollision.scala @@ -3,8 +3,7 @@ package smithy4s.example import smithy4s.Errorable import smithy4s.Schema import smithy4s.schema.Schema.unit -import smithy4s.Transformation -import smithy4s.Monadic +import smithy4s.kinds.PolyFunction5 import smithy4s.Service import smithy4s.ShapeTag import smithy4s.schema.Schema.bijection @@ -12,6 +11,8 @@ import smithy4s.schema.Schema.union import smithy4s.schema.Schema.UnionSchema import smithy4s.Hints import smithy4s.StreamingSchema +import smithy4s.kinds.FunctorAlgebra +import smithy4s.capability.Transformation import smithy4s.ShapeId import smithy4s.Endpoint @@ -20,15 +21,12 @@ trait NameCollisionGen[F[_, _, _, _, _]] { def myOp() : F[Unit, NameCollisionGen.MyOpError, Unit, Nothing, Nothing] - def transform[G[_, _, _, _, _]](transformation : Transformation[F, G]) : NameCollisionGen[G] = new Transformed(transformation) - class Transformed[G[_, _, _, _, _]](transformation : Transformation[F, G]) extends NameCollisionGen[G] { - def myOp() = transformation[Unit, NameCollisionGen.MyOpError, Unit, Nothing, Nothing](self.myOp()) - } + def transform : Transformation.PartiallyApplied[NameCollisionGen[F]] = new Transformation.PartiallyApplied[NameCollisionGen[F]](this) } object NameCollisionGen extends Service[NameCollisionGen, NameCollisionOperation] { - def apply[F[_]](implicit F: Monadic[NameCollisionGen, F]): F.type = F + def apply[F[_]](implicit F: FunctorAlgebra[NameCollisionGen, F]): F.type = F val id: ShapeId = ShapeId("smithy4s.example", "NameCollision") @@ -48,11 +46,14 @@ object NameCollisionGen extends Service[NameCollisionGen, NameCollisionOperation def myOp() = MyOp() } - def transform[P[_, _, _, _, _]](transformation: Transformation[NameCollisionOperation, P]): NameCollisionGen[P] = reified.transform(transformation) + def mapK5[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: NameCollisionGen[P], f: PolyFunction5[P, P1]): NameCollisionGen[P1] = new Transformed(alg, f) - def transform[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: NameCollisionGen[P], transformation: Transformation[P, P1]): NameCollisionGen[P1] = alg.transform(transformation) + def fromPolyFunction[P[_, _, _, _, _]](f: PolyFunction5[NameCollisionOperation, P]): NameCollisionGen[P] = new Transformed(reified, f) + class Transformed[P[_, _, _, _, _], P1[_ ,_ ,_ ,_ ,_]](alg: NameCollisionGen[P], f : PolyFunction5[P, P1]) extends NameCollisionGen[P1] { + def myOp() = f[Unit, NameCollisionGen.MyOpError, Unit, Nothing, Nothing](alg.myOp()) + } - def asTransformation[P[_, _, _, _, _]](impl : NameCollisionGen[P]): Transformation[NameCollisionOperation, P] = new Transformation[NameCollisionOperation, P] { + def toPolyFunction[P[_, _, _, _, _]](impl : NameCollisionGen[P]): PolyFunction5[NameCollisionOperation, P] = new PolyFunction5[NameCollisionOperation, P] { def apply[I, E, O, SI, SO](op : NameCollisionOperation[I, E, O, SI, SO]) : P[I, E, O, SI, SO] = op match { case MyOp() => impl.myOp() } diff --git a/modules/example/src/smithy4s/example/ObjectService.scala b/modules/example/src/smithy4s/example/ObjectService.scala index 805fa0f45..563a3c0d4 100644 --- a/modules/example/src/smithy4s/example/ObjectService.scala +++ b/modules/example/src/smithy4s/example/ObjectService.scala @@ -3,8 +3,7 @@ package smithy4s.example import smithy4s.Errorable import smithy4s.Schema import smithy4s.schema.Schema.unit -import smithy4s.Transformation -import smithy4s.Monadic +import smithy4s.kinds.PolyFunction5 import smithy4s.Service import smithy4s.ShapeTag import smithy4s.schema.Schema.bijection @@ -12,6 +11,8 @@ import smithy4s.schema.Schema.union import smithy4s.schema.Schema.UnionSchema import smithy4s.Hints import smithy4s.StreamingSchema +import smithy4s.kinds.FunctorAlgebra +import smithy4s.capability.Transformation import smithy4s.ShapeId import smithy4s.Endpoint @@ -21,16 +22,12 @@ trait ObjectServiceGen[F[_, _, _, _, _]] { def putObject(key: ObjectKey, bucketName: BucketName, data: String, foo: Option[LowHigh] = None, someValue: Option[SomeValue] = None) : F[PutObjectInput, ObjectServiceGen.PutObjectError, Unit, Nothing, Nothing] def getObject(key: ObjectKey, bucketName: BucketName) : F[GetObjectInput, ObjectServiceGen.GetObjectError, GetObjectOutput, Nothing, Nothing] - def transform[G[_, _, _, _, _]](transformation : Transformation[F, G]) : ObjectServiceGen[G] = new Transformed(transformation) - class Transformed[G[_, _, _, _, _]](transformation : Transformation[F, G]) extends ObjectServiceGen[G] { - def putObject(key: ObjectKey, bucketName: BucketName, data: String, foo: Option[LowHigh] = None, someValue: Option[SomeValue] = None) = transformation[PutObjectInput, ObjectServiceGen.PutObjectError, Unit, Nothing, Nothing](self.putObject(key, bucketName, data, foo, someValue)) - def getObject(key: ObjectKey, bucketName: BucketName) = transformation[GetObjectInput, ObjectServiceGen.GetObjectError, GetObjectOutput, Nothing, Nothing](self.getObject(key, bucketName)) - } + def transform : Transformation.PartiallyApplied[ObjectServiceGen[F]] = new Transformation.PartiallyApplied[ObjectServiceGen[F]](this) } object ObjectServiceGen extends Service[ObjectServiceGen, ObjectServiceOperation] { - def apply[F[_]](implicit F: Monadic[ObjectServiceGen, F]): F.type = F + def apply[F[_]](implicit F: FunctorAlgebra[ObjectServiceGen, F]): F.type = F val id: ShapeId = ShapeId("smithy4s.example", "ObjectService") @@ -55,11 +52,15 @@ object ObjectServiceGen extends Service[ObjectServiceGen, ObjectServiceOperation def getObject(key: ObjectKey, bucketName: BucketName) = GetObject(GetObjectInput(key, bucketName)) } - def transform[P[_, _, _, _, _]](transformation: Transformation[ObjectServiceOperation, P]): ObjectServiceGen[P] = reified.transform(transformation) + def mapK5[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: ObjectServiceGen[P], f: PolyFunction5[P, P1]): ObjectServiceGen[P1] = new Transformed(alg, f) - def transform[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: ObjectServiceGen[P], transformation: Transformation[P, P1]): ObjectServiceGen[P1] = alg.transform(transformation) + def fromPolyFunction[P[_, _, _, _, _]](f: PolyFunction5[ObjectServiceOperation, P]): ObjectServiceGen[P] = new Transformed(reified, f) + class Transformed[P[_, _, _, _, _], P1[_ ,_ ,_ ,_ ,_]](alg: ObjectServiceGen[P], f : PolyFunction5[P, P1]) extends ObjectServiceGen[P1] { + def putObject(key: ObjectKey, bucketName: BucketName, data: String, foo: Option[LowHigh] = None, someValue: Option[SomeValue] = None) = f[PutObjectInput, ObjectServiceGen.PutObjectError, Unit, Nothing, Nothing](alg.putObject(key, bucketName, data, foo, someValue)) + def getObject(key: ObjectKey, bucketName: BucketName) = f[GetObjectInput, ObjectServiceGen.GetObjectError, GetObjectOutput, Nothing, Nothing](alg.getObject(key, bucketName)) + } - def asTransformation[P[_, _, _, _, _]](impl : ObjectServiceGen[P]): Transformation[ObjectServiceOperation, P] = new Transformation[ObjectServiceOperation, P] { + def toPolyFunction[P[_, _, _, _, _]](impl : ObjectServiceGen[P]): PolyFunction5[ObjectServiceOperation, P] = new PolyFunction5[ObjectServiceOperation, P] { def apply[I, E, O, SI, SO](op : ObjectServiceOperation[I, E, O, SI, SO]) : P[I, E, O, SI, SO] = op match { case PutObject(PutObjectInput(key, bucketName, data, foo, someValue)) => impl.putObject(key, bucketName, data, foo, someValue) case GetObject(GetObjectInput(key, bucketName)) => impl.getObject(key, bucketName) diff --git a/modules/example/src/smithy4s/example/StreamedObjects.scala b/modules/example/src/smithy4s/example/StreamedObjects.scala index fc97a7a8b..fddeca094 100644 --- a/modules/example/src/smithy4s/example/StreamedObjects.scala +++ b/modules/example/src/smithy4s/example/StreamedObjects.scala @@ -2,11 +2,12 @@ package smithy4s.example import smithy4s.Schema import smithy4s.schema.Schema.unit -import smithy4s.Transformation -import smithy4s.Monadic +import smithy4s.kinds.PolyFunction5 import smithy4s.Service import smithy4s.Hints import smithy4s.StreamingSchema +import smithy4s.kinds.FunctorAlgebra +import smithy4s.capability.Transformation import smithy4s.ShapeId import smithy4s.Endpoint @@ -16,16 +17,12 @@ trait StreamedObjectsGen[F[_, _, _, _, _]] { def putStreamedObject(key: String) : F[PutStreamedObjectInput, Nothing, Unit, StreamedBlob, Nothing] def getStreamedObject(key: String) : F[GetStreamedObjectInput, Nothing, GetStreamedObjectOutput, Nothing, StreamedBlob] - def transform[G[_, _, _, _, _]](transformation : Transformation[F, G]) : StreamedObjectsGen[G] = new Transformed(transformation) - class Transformed[G[_, _, _, _, _]](transformation : Transformation[F, G]) extends StreamedObjectsGen[G] { - def putStreamedObject(key: String) = transformation[PutStreamedObjectInput, Nothing, Unit, StreamedBlob, Nothing](self.putStreamedObject(key)) - def getStreamedObject(key: String) = transformation[GetStreamedObjectInput, Nothing, GetStreamedObjectOutput, Nothing, StreamedBlob](self.getStreamedObject(key)) - } + def transform : Transformation.PartiallyApplied[StreamedObjectsGen[F]] = new Transformation.PartiallyApplied[StreamedObjectsGen[F]](this) } object StreamedObjectsGen extends Service[StreamedObjectsGen, StreamedObjectsOperation] { - def apply[F[_]](implicit F: Monadic[StreamedObjectsGen, F]): F.type = F + def apply[F[_]](implicit F: FunctorAlgebra[StreamedObjectsGen, F]): F.type = F val id: ShapeId = ShapeId("smithy4s.example", "StreamedObjects") @@ -48,11 +45,15 @@ object StreamedObjectsGen extends Service[StreamedObjectsGen, StreamedObjectsOpe def getStreamedObject(key: String) = GetStreamedObject(GetStreamedObjectInput(key)) } - def transform[P[_, _, _, _, _]](transformation: Transformation[StreamedObjectsOperation, P]): StreamedObjectsGen[P] = reified.transform(transformation) + def mapK5[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: StreamedObjectsGen[P], f: PolyFunction5[P, P1]): StreamedObjectsGen[P1] = new Transformed(alg, f) - def transform[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: StreamedObjectsGen[P], transformation: Transformation[P, P1]): StreamedObjectsGen[P1] = alg.transform(transformation) + def fromPolyFunction[P[_, _, _, _, _]](f: PolyFunction5[StreamedObjectsOperation, P]): StreamedObjectsGen[P] = new Transformed(reified, f) + class Transformed[P[_, _, _, _, _], P1[_ ,_ ,_ ,_ ,_]](alg: StreamedObjectsGen[P], f : PolyFunction5[P, P1]) extends StreamedObjectsGen[P1] { + def putStreamedObject(key: String) = f[PutStreamedObjectInput, Nothing, Unit, StreamedBlob, Nothing](alg.putStreamedObject(key)) + def getStreamedObject(key: String) = f[GetStreamedObjectInput, Nothing, GetStreamedObjectOutput, Nothing, StreamedBlob](alg.getStreamedObject(key)) + } - def asTransformation[P[_, _, _, _, _]](impl : StreamedObjectsGen[P]): Transformation[StreamedObjectsOperation, P] = new Transformation[StreamedObjectsOperation, P] { + def toPolyFunction[P[_, _, _, _, _]](impl : StreamedObjectsGen[P]): PolyFunction5[StreamedObjectsOperation, P] = new PolyFunction5[StreamedObjectsOperation, P] { def apply[I, E, O, SI, SO](op : StreamedObjectsOperation[I, E, O, SI, SO]) : P[I, E, O, SI, SO] = op match { case PutStreamedObject(PutStreamedObjectInput(key)) => impl.putStreamedObject(key) case GetStreamedObject(GetStreamedObjectInput(key)) => impl.getStreamedObject(key) diff --git a/modules/example/src/smithy4s/example/collision/ReservedNameService.scala b/modules/example/src/smithy4s/example/collision/ReservedNameService.scala index 946805e41..c3c47de32 100644 --- a/modules/example/src/smithy4s/example/collision/ReservedNameService.scala +++ b/modules/example/src/smithy4s/example/collision/ReservedNameService.scala @@ -2,11 +2,12 @@ package smithy4s.example.collision import smithy4s.Schema import smithy4s.schema.Schema.unit -import smithy4s.Transformation -import smithy4s.Monadic +import smithy4s.kinds.PolyFunction5 import smithy4s.Service import smithy4s.Hints import smithy4s.StreamingSchema +import smithy4s.kinds.FunctorAlgebra +import smithy4s.capability.Transformation import smithy4s.ShapeId import smithy4s.Endpoint @@ -18,18 +19,12 @@ trait ReservedNameServiceGen[F[_, _, _, _, _]] { def map(value: Map[String,String]) : F[MapInput, Nothing, Unit, Nothing, Nothing] def option(value: Option[String] = None) : F[OptionInput, Nothing, Unit, Nothing, Nothing] - def transform[G[_, _, _, _, _]](transformation : Transformation[F, G]) : ReservedNameServiceGen[G] = new Transformed(transformation) - class Transformed[G[_, _, _, _, _]](transformation : Transformation[F, G]) extends ReservedNameServiceGen[G] { - def set(set: Set[String]) = transformation[SetInput, Nothing, Unit, Nothing, Nothing](self.set(set)) - def list(list: List[String]) = transformation[ListInput, Nothing, Unit, Nothing, Nothing](self.list(list)) - def map(value: Map[String,String]) = transformation[MapInput, Nothing, Unit, Nothing, Nothing](self.map(value)) - def option(value: Option[String] = None) = transformation[OptionInput, Nothing, Unit, Nothing, Nothing](self.option(value)) - } + def transform : Transformation.PartiallyApplied[ReservedNameServiceGen[F]] = new Transformation.PartiallyApplied[ReservedNameServiceGen[F]](this) } object ReservedNameServiceGen extends Service[ReservedNameServiceGen, ReservedNameServiceOperation] { - def apply[F[_]](implicit F: Monadic[ReservedNameServiceGen, F]): F.type = F + def apply[F[_]](implicit F: FunctorAlgebra[ReservedNameServiceGen, F]): F.type = F val id: ShapeId = ShapeId("smithy4s.example.collision", "ReservedNameService") @@ -60,11 +55,17 @@ object ReservedNameServiceGen extends Service[ReservedNameServiceGen, ReservedNa def option(value: Option[String] = None) = _Option(OptionInput(value)) } - def transform[P[_, _, _, _, _]](transformation: Transformation[ReservedNameServiceOperation, P]): ReservedNameServiceGen[P] = reified.transform(transformation) + def mapK5[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: ReservedNameServiceGen[P], f: PolyFunction5[P, P1]): ReservedNameServiceGen[P1] = new Transformed(alg, f) - def transform[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: ReservedNameServiceGen[P], transformation: Transformation[P, P1]): ReservedNameServiceGen[P1] = alg.transform(transformation) + def fromPolyFunction[P[_, _, _, _, _]](f: PolyFunction5[ReservedNameServiceOperation, P]): ReservedNameServiceGen[P] = new Transformed(reified, f) + class Transformed[P[_, _, _, _, _], P1[_ ,_ ,_ ,_ ,_]](alg: ReservedNameServiceGen[P], f : PolyFunction5[P, P1]) extends ReservedNameServiceGen[P1] { + def set(set: Set[String]) = f[SetInput, Nothing, Unit, Nothing, Nothing](alg.set(set)) + def list(list: List[String]) = f[ListInput, Nothing, Unit, Nothing, Nothing](alg.list(list)) + def map(value: Map[String,String]) = f[MapInput, Nothing, Unit, Nothing, Nothing](alg.map(value)) + def option(value: Option[String] = None) = f[OptionInput, Nothing, Unit, Nothing, Nothing](alg.option(value)) + } - def asTransformation[P[_, _, _, _, _]](impl : ReservedNameServiceGen[P]): Transformation[ReservedNameServiceOperation, P] = new Transformation[ReservedNameServiceOperation, P] { + def toPolyFunction[P[_, _, _, _, _]](impl : ReservedNameServiceGen[P]): PolyFunction5[ReservedNameServiceOperation, P] = new PolyFunction5[ReservedNameServiceOperation, P] { def apply[I, E, O, SI, SO](op : ReservedNameServiceOperation[I, E, O, SI, SO]) : P[I, E, O, SI, SO] = op match { case _Set(SetInput(set)) => impl.set(set) case _List(ListInput(list)) => impl.list(list) diff --git a/modules/example/src/smithy4s/example/collision/package.scala b/modules/example/src/smithy4s/example/collision/package.scala index e139a8eb1..d77c6ee9a 100644 --- a/modules/example/src/smithy4s/example/collision/package.scala +++ b/modules/example/src/smithy4s/example/collision/package.scala @@ -1,7 +1,7 @@ package smithy4s.example package object collision { - type ReservedNameService[F[_]] = smithy4s.Monadic[ReservedNameServiceGen, F] + type ReservedNameService[F[_]] = smithy4s.kinds.FunctorAlgebra[ReservedNameServiceGen, F] object ReservedNameService extends smithy4s.Service.Provider[ReservedNameServiceGen, ReservedNameServiceOperation] { def apply[F[_]](implicit F: ReservedNameService[F]): F.type = F def service: smithy4s.Service[ReservedNameServiceGen, ReservedNameServiceOperation] = ReservedNameServiceGen diff --git a/modules/example/src/smithy4s/example/imp/ImportService.scala b/modules/example/src/smithy4s/example/imp/ImportService.scala index accfe2250..9379573a2 100644 --- a/modules/example/src/smithy4s/example/imp/ImportService.scala +++ b/modules/example/src/smithy4s/example/imp/ImportService.scala @@ -4,8 +4,7 @@ import smithy4s.Errorable import smithy4s.example.import_test.OpOutput import smithy4s.Schema import smithy4s.schema.Schema.unit -import smithy4s.Transformation -import smithy4s.Monadic +import smithy4s.kinds.PolyFunction5 import smithy4s.Service import smithy4s.ShapeTag import smithy4s.schema.Schema.bijection @@ -14,6 +13,8 @@ import smithy4s.schema.Schema.union import smithy4s.schema.Schema.UnionSchema import smithy4s.Hints import smithy4s.StreamingSchema +import smithy4s.kinds.FunctorAlgebra +import smithy4s.capability.Transformation import smithy4s.ShapeId import smithy4s.Endpoint @@ -22,15 +23,12 @@ trait ImportServiceGen[F[_, _, _, _, _]] { def importOperation() : F[Unit, ImportServiceGen.ImportOperationError, OpOutput, Nothing, Nothing] - def transform[G[_, _, _, _, _]](transformation : Transformation[F, G]) : ImportServiceGen[G] = new Transformed(transformation) - class Transformed[G[_, _, _, _, _]](transformation : Transformation[F, G]) extends ImportServiceGen[G] { - def importOperation() = transformation[Unit, ImportServiceGen.ImportOperationError, OpOutput, Nothing, Nothing](self.importOperation()) - } + def transform : Transformation.PartiallyApplied[ImportServiceGen[F]] = new Transformation.PartiallyApplied[ImportServiceGen[F]](this) } object ImportServiceGen extends Service[ImportServiceGen, ImportServiceOperation] { - def apply[F[_]](implicit F: Monadic[ImportServiceGen, F]): F.type = F + def apply[F[_]](implicit F: FunctorAlgebra[ImportServiceGen, F]): F.type = F val id: ShapeId = ShapeId("smithy4s.example.imp", "ImportService") @@ -52,11 +50,14 @@ object ImportServiceGen extends Service[ImportServiceGen, ImportServiceOperation def importOperation() = ImportOperation() } - def transform[P[_, _, _, _, _]](transformation: Transformation[ImportServiceOperation, P]): ImportServiceGen[P] = reified.transform(transformation) + def mapK5[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: ImportServiceGen[P], f: PolyFunction5[P, P1]): ImportServiceGen[P1] = new Transformed(alg, f) - def transform[P[_, _, _, _, _], P1[_, _, _, _, _]](alg: ImportServiceGen[P], transformation: Transformation[P, P1]): ImportServiceGen[P1] = alg.transform(transformation) + def fromPolyFunction[P[_, _, _, _, _]](f: PolyFunction5[ImportServiceOperation, P]): ImportServiceGen[P] = new Transformed(reified, f) + class Transformed[P[_, _, _, _, _], P1[_ ,_ ,_ ,_ ,_]](alg: ImportServiceGen[P], f : PolyFunction5[P, P1]) extends ImportServiceGen[P1] { + def importOperation() = f[Unit, ImportServiceGen.ImportOperationError, OpOutput, Nothing, Nothing](alg.importOperation()) + } - def asTransformation[P[_, _, _, _, _]](impl : ImportServiceGen[P]): Transformation[ImportServiceOperation, P] = new Transformation[ImportServiceOperation, P] { + def toPolyFunction[P[_, _, _, _, _]](impl : ImportServiceGen[P]): PolyFunction5[ImportServiceOperation, P] = new PolyFunction5[ImportServiceOperation, P] { def apply[I, E, O, SI, SO](op : ImportServiceOperation[I, E, O, SI, SO]) : P[I, E, O, SI, SO] = op match { case ImportOperation() => impl.importOperation() } diff --git a/modules/example/src/smithy4s/example/imp/package.scala b/modules/example/src/smithy4s/example/imp/package.scala index bd905345f..c220e0d78 100644 --- a/modules/example/src/smithy4s/example/imp/package.scala +++ b/modules/example/src/smithy4s/example/imp/package.scala @@ -1,7 +1,7 @@ package smithy4s.example package object imp { - type ImportService[F[_]] = smithy4s.Monadic[ImportServiceGen, F] + type ImportService[F[_]] = smithy4s.kinds.FunctorAlgebra[ImportServiceGen, F] object ImportService extends smithy4s.Service.Provider[ImportServiceGen, ImportServiceOperation] { def apply[F[_]](implicit F: ImportService[F]): F.type = F def service: smithy4s.Service[ImportServiceGen, ImportServiceOperation] = ImportServiceGen diff --git a/modules/example/src/smithy4s/example/package.scala b/modules/example/src/smithy4s/example/package.scala index c2e93e501..17252024c 100644 --- a/modules/example/src/smithy4s/example/package.scala +++ b/modules/example/src/smithy4s/example/package.scala @@ -1,31 +1,31 @@ package smithy4s package object example { - type StreamedObjects[F[_]] = smithy4s.Monadic[StreamedObjectsGen, F] + type StreamedObjects[F[_]] = smithy4s.kinds.FunctorAlgebra[StreamedObjectsGen, F] object StreamedObjects extends smithy4s.Service.Provider[StreamedObjectsGen, StreamedObjectsOperation] { def apply[F[_]](implicit F: StreamedObjects[F]): F.type = F def service: smithy4s.Service[StreamedObjectsGen, StreamedObjectsOperation] = StreamedObjectsGen val id: smithy4s.ShapeId = service.id } - type FooService[F[_]] = smithy4s.Monadic[FooServiceGen, F] + type FooService[F[_]] = smithy4s.kinds.FunctorAlgebra[FooServiceGen, F] object FooService extends smithy4s.Service.Provider[FooServiceGen, FooServiceOperation] { def apply[F[_]](implicit F: FooService[F]): F.type = F def service: smithy4s.Service[FooServiceGen, FooServiceOperation] = FooServiceGen val id: smithy4s.ShapeId = service.id } - type BrandService[F[_]] = smithy4s.Monadic[BrandServiceGen, F] + type BrandService[F[_]] = smithy4s.kinds.FunctorAlgebra[BrandServiceGen, F] object BrandService extends smithy4s.Service.Provider[BrandServiceGen, BrandServiceOperation] { def apply[F[_]](implicit F: BrandService[F]): F.type = F def service: smithy4s.Service[BrandServiceGen, BrandServiceOperation] = BrandServiceGen val id: smithy4s.ShapeId = service.id } - type ObjectService[F[_]] = smithy4s.Monadic[ObjectServiceGen, F] + type ObjectService[F[_]] = smithy4s.kinds.FunctorAlgebra[ObjectServiceGen, F] object ObjectService extends smithy4s.Service.Provider[ObjectServiceGen, ObjectServiceOperation] { def apply[F[_]](implicit F: ObjectService[F]): F.type = F def service: smithy4s.Service[ObjectServiceGen, ObjectServiceOperation] = ObjectServiceGen val id: smithy4s.ShapeId = service.id } - type NameCollision[F[_]] = smithy4s.Monadic[NameCollisionGen, F] + type NameCollision[F[_]] = smithy4s.kinds.FunctorAlgebra[NameCollisionGen, F] object NameCollision extends smithy4s.Service.Provider[NameCollisionGen, NameCollisionOperation] { def apply[F[_]](implicit F: NameCollision[F]): F.type = F def service: smithy4s.Service[NameCollisionGen, NameCollisionOperation] = NameCollisionGen diff --git a/modules/http4s/src/smithy4s/http4s/SimpleProtocolBuilder.scala b/modules/http4s/src/smithy4s/http4s/SimpleProtocolBuilder.scala index 13a65b95c..7b8fa85ee 100644 --- a/modules/http4s/src/smithy4s/http4s/SimpleProtocolBuilder.scala +++ b/modules/http4s/src/smithy4s/http4s/SimpleProtocolBuilder.scala @@ -24,6 +24,7 @@ import org.http4s.Uri import org.http4s.client.Client import smithy4s.http.CodecAPI import org.http4s.implicits._ +import smithy4s.kinds._ /** * Abstract construct helping the construction of routers and clients @@ -39,7 +40,7 @@ abstract class SimpleProtocolBuilder[P](val codecs: CodecAPI)(implicit ): ServiceBuilder[Alg, Op] = new ServiceBuilder(serviceProvider.service) def routes[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _], F[_]]( - impl: Monadic[Alg, F] + impl: FunctorAlgebra[Alg, F] )(implicit serviceProvider: smithy4s.Service.Provider[Alg, Op], F: EffectCompat[F] @@ -47,7 +48,7 @@ abstract class SimpleProtocolBuilder[P](val codecs: CodecAPI)(implicit val service = serviceProvider.service new RouterBuilder[Alg, Op, F]( service, - service.asTransformation[GenLift[F]#λ](impl), + service.toPolyFunction[Kind1[F]#toKind5](impl), PartialFunction.empty ) } @@ -65,7 +66,7 @@ abstract class SimpleProtocolBuilder[P](val codecs: CodecAPI)(implicit def client[F[_]: EffectCompat]( http4sClient: Client[F], baseUri: Uri - ): Either[UnsupportedProtocolError, Monadic[Alg, F]] = + ): Either[UnsupportedProtocolError, FunctorAlgebra[Alg, F]] = client(http4sClient).uri(baseUri).use @deprecated( @@ -74,14 +75,15 @@ abstract class SimpleProtocolBuilder[P](val codecs: CodecAPI)(implicit def clientResource[F[_]: EffectCompat]( http4sClient: Client[F], baseUri: Uri - ): Resource[F, Monadic[Alg, F]] = client(http4sClient).uri(baseUri).resource + ): Resource[F, FunctorAlgebra[Alg, F]] = + client(http4sClient).uri(baseUri).resource def routes[F[_]: EffectCompat]( - impl: Monadic[Alg, F] + impl: FunctorAlgebra[Alg, F] ): RouterBuilder[Alg, Op, F] = new RouterBuilder[Alg, Op, F]( service, - service.asTransformation[GenLift[F]#λ](impl), + service.toPolyFunction[Kind1[F]#toKind5](impl), PartialFunction.empty ) @@ -98,10 +100,10 @@ abstract class SimpleProtocolBuilder[P](val codecs: CodecAPI)(implicit def uri(uri: Uri): ClientBuilder[Alg, Op, F] = new ClientBuilder[Alg, Op, F](this.client, this.service, uri) - def resource: Resource[F, Monadic[Alg, F]] = + def resource: Resource[F, FunctorAlgebra[Alg, F]] = use.leftWiden[Throwable].liftTo[Resource[F, *]] - def use: Either[UnsupportedProtocolError, Monadic[Alg, F]] = { + def use: Either[UnsupportedProtocolError, FunctorAlgebra[Alg, F]] = { checkProtocol(service, protocolTag) .as( new SmithyHttp4sReverseRouter[Alg, Op, F]( @@ -112,7 +114,7 @@ abstract class SimpleProtocolBuilder[P](val codecs: CodecAPI)(implicit .fromCodecAPI[F](codecs) ) ) - .map(service.transform[GenLift[F]#λ](_)) + .map(service.fromPolyFunction[Kind1[F]#toKind5](_)) } } @@ -122,7 +124,7 @@ abstract class SimpleProtocolBuilder[P](val codecs: CodecAPI)(implicit F[_] ] private[http4s] ( service: smithy4s.Service[Alg, Op], - impl: Interpreter[Op, F], + impl: FunctorInterpreter[Op, F], errorTransformation: PartialFunction[Throwable, F[Throwable]] )(implicit F: EffectCompat[F]) { diff --git a/modules/http4s/src/smithy4s/http4s/SmithyHttp4sReverseRouter.scala b/modules/http4s/src/smithy4s/http4s/SmithyHttp4sReverseRouter.scala index 3b06042df..3c2c27ddb 100644 --- a/modules/http4s/src/smithy4s/http4s/SmithyHttp4sReverseRouter.scala +++ b/modules/http4s/src/smithy4s/http4s/SmithyHttp4sReverseRouter.scala @@ -17,6 +17,7 @@ package smithy4s package http4s +import smithy4s.kinds._ import org.http4s._ import org.http4s.client.Client import smithy4s.http4s.internals.SmithyHttp4sClientEndpoint @@ -28,7 +29,7 @@ class SmithyHttp4sReverseRouter[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _], F[_]]( client: Client[F], entityCompiler: EntityCompiler[F] )(implicit effect: EffectCompat[F]) - extends Interpreter[Op, F] { + extends FunctorInterpreter[Op, F] { // format: on private val compilerContext = internals.CompilerContext.make(entityCompiler) @@ -42,7 +43,7 @@ class SmithyHttp4sReverseRouter[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _], F[_]]( } private val clientEndpoints = - new Transformation[ + new PolyFunction5[ Endpoint[Op, *, *, *, *, *], SmithyHttp4sClientEndpoint[F, Op, *, *, *, *, *] ] { @@ -59,5 +60,8 @@ class SmithyHttp4sReverseRouter[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _], F[_]]( s"Operation ${endpoint.name} is not bound to http semantics" ) ) - }.precompute(service.endpoints.map(smithy4s.Kind5.existential(_))) + }.unsafeCacheBy( + service.endpoints.map(smithy4s.kinds.Kind5.existential(_)), + identity + ) } diff --git a/modules/http4s/src/smithy4s/http4s/SmithyHttp4sRouter.scala b/modules/http4s/src/smithy4s/http4s/SmithyHttp4sRouter.scala index acd8795fa..94c445670 100644 --- a/modules/http4s/src/smithy4s/http4s/SmithyHttp4sRouter.scala +++ b/modules/http4s/src/smithy4s/http4s/SmithyHttp4sRouter.scala @@ -22,11 +22,12 @@ import cats.data.OptionT import cats.implicits._ import org.http4s._ import smithy4s.http4s.internals.SmithyHttp4sServerEndpoint +import smithy4s.kinds._ // format: off class SmithyHttp4sRouter[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _], F[_]]( service: smithy4s.Service[Alg, Op], - impl: Interpreter[Op, F], + impl: FunctorInterpreter[Op, F], errorTransformation: PartialFunction[Throwable, F[Throwable]], entityCompiler: EntityCompiler[F] )(implicit effect: EffectCompat[F]) { diff --git a/modules/http4s/src/smithy4s/http4s/internals/SmithyHttp4sClientEndpoint.scala b/modules/http4s/src/smithy4s/http4s/internals/SmithyHttp4sClientEndpoint.scala index 4b83e8cf3..5e726e6b4 100644 --- a/modules/http4s/src/smithy4s/http4s/internals/SmithyHttp4sClientEndpoint.scala +++ b/modules/http4s/src/smithy4s/http4s/internals/SmithyHttp4sClientEndpoint.scala @@ -27,6 +27,7 @@ import org.http4s.Uri import org.http4s.client.Client import smithy4s.http._ import smithy4s.schema.SchemaAlt +import smithy4s.kinds._ /** * A construct that encapsulates interprets and a low-level @@ -163,7 +164,7 @@ private[smithy4s] class SmithyHttp4sClientEndpointImpl[F[_], Op[_, _, _, _, _], .map(alt.inject) } } - }.unsafeCache(allAlternatives.map(Existential.wrap(_))) + }.unsafeCacheBy(allAlternatives.map(Kind1.existential(_)), identity(_)) (response: Response[F]) => { val discriminator = getErrorDiscriminator(response) diff --git a/modules/http4s/src/smithy4s/http4s/internals/SmithyHttp4sServerEndpoint.scala b/modules/http4s/src/smithy4s/http4s/internals/SmithyHttp4sServerEndpoint.scala index aa5b20c50..6c630de29 100644 --- a/modules/http4s/src/smithy4s/http4s/internals/SmithyHttp4sServerEndpoint.scala +++ b/modules/http4s/src/smithy4s/http4s/internals/SmithyHttp4sServerEndpoint.scala @@ -30,6 +30,7 @@ import org.http4s.Status import smithy4s.http.Metadata import smithy4s.http._ import smithy4s.schema.Alt +import smithy4s.kinds._ /** * A construct that encapsulates a smithy4s endpoint, and exposes @@ -49,7 +50,7 @@ private[smithy4s] trait SmithyHttp4sServerEndpoint[F[_]] { private[smithy4s] object SmithyHttp4sServerEndpoint { def apply[F[_]: EffectCompat, Op[_, _, _, _, _], I, E, O, SI, SO]( - impl: Interpreter[Op, F], + impl: FunctorInterpreter[Op, F], endpoint: Endpoint[Op, I, E, O, SI, SO], compilerContext: CompilerContext[F], errorTransformation: PartialFunction[Throwable, F[Throwable]] @@ -68,7 +69,7 @@ private[smithy4s] object SmithyHttp4sServerEndpoint { // format: off private[smithy4s] class SmithyHttp4sServerEndpointImpl[F[_], Op[_, _, _, _, _], I, E, O, SI, SO]( - impl: Interpreter[Op, F], + impl: FunctorInterpreter[Op, F], endpoint: Endpoint[Op, I, E, O, SI, SO], httpEndpoint: HttpEndpoint[I], compilerContext: CompilerContext[F], diff --git a/modules/http4s/test/src-jvm/smithy4s/http4s/Http4sDynamicPizzaClientSpec.scala b/modules/http4s/test/src-jvm/smithy4s/http4s/Http4sDynamicPizzaClientSpec.scala index e9442ea34..0cc19fd44 100644 --- a/modules/http4s/test/src-jvm/smithy4s/http4s/Http4sDynamicPizzaClientSpec.scala +++ b/modules/http4s/test/src-jvm/smithy4s/http4s/Http4sDynamicPizzaClientSpec.scala @@ -43,7 +43,7 @@ class DynamicHttpProxy(client: Client[IO]) { .getOrElse(sys.error("service not found in DSI")) } - val dynamicPizza: IO[smithy4s.Monadic[PizzaAdminServiceGen, IO]] = + val dynamicPizza: IO[PizzaAdminService[IO]] = dynamicServiceIO .flatMap { dsi => SimpleRestJsonBuilder(dsi.service) diff --git a/modules/test-utils/src/smithy4s/tests/DummyService.scala b/modules/test-utils/src/smithy4s/tests/DummyService.scala index 1b6b2da38..0d7aa969f 100644 --- a/modules/test-utils/src/smithy4s/tests/DummyService.scala +++ b/modules/test-utils/src/smithy4s/tests/DummyService.scala @@ -18,6 +18,7 @@ package smithy4s package tests import cats.Applicative +import smithy4s.kinds._ object DummyService { @@ -27,10 +28,10 @@ object DummyService { def create[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _]](implicit service: Service[Alg, Op], F: Applicative[F] - ): smithy4s.Monadic[Alg, F] = { - service.transform[GenLift[F]#λ] { - service.opToEndpoint.andThen[GenLift[F]#λ]( - new Transformation[Endpoint[Op, *, *, *, *, *], GenLift[F]#λ] { + ): FunctorAlgebra[Alg, F] = { + service.fromPolyFunction[Kind1[F]#toKind5] { + service.opToEndpoint.andThen[Kind1[F]#toKind5]( + new PolyFunction5[Endpoint[Op, *, *, *, *, *], Kind1[F]#toKind5] { def apply[I, E, O, SI, SO]( ep: Endpoint[Op, I, E, O, SI, SO] ): F[O] = diff --git a/modules/test-utils/src/smithy4s/tests/JsonProtocolF.scala b/modules/test-utils/src/smithy4s/tests/JsonProtocolF.scala index 3f999e40b..c5667eef9 100644 --- a/modules/test-utils/src/smithy4s/tests/JsonProtocolF.scala +++ b/modules/test-utils/src/smithy4s/tests/JsonProtocolF.scala @@ -21,6 +21,7 @@ import Document._ import cats.syntax.all._ import cats.MonadThrow +import smithy4s.kinds._ /** * These are toy interpreters that turn services into json-in/json-out @@ -54,22 +55,25 @@ class JsonProtocolF[F[_]](implicit F: MonadThrow[F]) { def fromJsonF[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _]]( jsonF: Document => F[Document] - )(implicit S: Service[Alg, Op]): Monadic[Alg, F] = { + )(implicit S: Service[Alg, Op]): FunctorAlgebra[Alg, F] = { val kleisliCache = - fromLowLevel(jsonF).precompute(S.endpoints.map(Kind5.existential(_))) - val transfo = new Transformation[Op, GenLift[F]#λ] { + fromLowLevel(jsonF).unsafeCacheBy( + S.endpoints.map(Kind5.existential(_)), + (ep: Kind5.Existential[Endpoint[Op, *, *, *, *, *]]) => ep + ) + val transfo = new PolyFunction5[Op, Kind1[F]#toKind5] { def apply[I, E, O, SI, SO](op: Op[I, E, O, SI, SO]): F[O] = { val (input, ep) = S.endpoint(op) kleisliCache(ep).apply(input) } } - S.transform[GenLift[F]#λ](transfo) + S.fromPolyFunction[Kind1[F]#toKind5](transfo) } def toJsonF[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _]]( - alg: Monadic[Alg, F] + alg: FunctorAlgebra[Alg, F] )(implicit S: Service[Alg, Op]): Document => F[Document] = { - val transformation = S.asTransformation[GenLift[F]#λ](alg) + val transformation = S.toPolyFunction[Kind1[F]#toKind5](alg) val jsonEndpoints = S.endpoints.map(ep => ep.name -> toLowLevel(transformation, ep)).toMap (d: Document) => { @@ -89,8 +93,8 @@ class JsonProtocolF[F[_]](implicit F: MonadThrow[F]) { private def fromLowLevel[Op[_, _, _, _, _]]( jsonF: Document => F[Document] - ): Transformation[Endpoint[Op, *, *, *, *, *], KL] = - new Transformation[Endpoint[Op, *, *, *, *, *], KL] { + ): PolyFunction5[Endpoint[Op, *, *, *, *, *], KL] = + new PolyFunction5[Endpoint[Op, *, *, *, *, *], KL] { def apply[I, E, O, SI, SO]( ep: Endpoint[Op, I, E, O, SI, SO] ): KL[I, E, O, SI, SO] = { @@ -137,7 +141,7 @@ class JsonProtocolF[F[_]](implicit F: MonadThrow[F]) { } private def toLowLevel[Op[_, _, _, _, _], I, E, O, SI, SO]( - transformation: Transformation[Op, GenLift[F]#λ], + polyFunction: PolyFunction5[Op, Kind1[F]#toKind5], endpoint: Endpoint[Op, I, E, O, SI, SO] ): Document => F[Document] = { implicit val decoderI = Document.Decoder.fromSchema(endpoint.input) @@ -155,7 +159,7 @@ class JsonProtocolF[F[_]](implicit F: MonadThrow[F]) { for { input <- document.decode[I].liftTo[F] op = endpoint.wrap(input) - output <- (transformation(op): F[O]).map(encoderO.encode).recover { + output <- (polyFunction(op): F[O]).map(encoderO.encode).recover { case endpoint.Error((_, e)) => Document.obj("error" -> encoderE.encode(e)) } diff --git a/modules/tests/src/smithy4s/tests/PizzaClientSpec.scala b/modules/tests/src/smithy4s/tests/PizzaClientSpec.scala index 7a02f9265..2a65f4dd9 100644 --- a/modules/tests/src/smithy4s/tests/PizzaClientSpec.scala +++ b/modules/tests/src/smithy4s/tests/PizzaClientSpec.scala @@ -197,7 +197,7 @@ abstract class PizzaClientSpec extends IOSuite { def clientTest(name: TestName)( f: ( - smithy4s.Monadic[PizzaAdminServiceGen, IO], + PizzaAdminService[IO], Backend, Log[IO] ) => IO[Expectations] @@ -206,13 +206,12 @@ abstract class PizzaClientSpec extends IOSuite { // If right, TCP will be exercised. def makeClient: Either[ - HttpApp[IO] => Resource[IO, smithy4s.Monadic[PizzaAdminServiceGen, IO]], - Int => Resource[IO, smithy4s.Monadic[PizzaAdminServiceGen, IO]] + HttpApp[IO] => Resource[IO, PizzaAdminService[IO]], + Int => Resource[IO, PizzaAdminService[IO]] ] - type Res = (smithy4s.Monadic[PizzaAdminServiceGen, IO], Backend) - def sharedResource - : Resource[IO, (smithy4s.Monadic[PizzaAdminServiceGen, IO], Backend)] = + type Res = (PizzaAdminService[IO], Backend) + def sharedResource: Resource[IO, (PizzaAdminService[IO], Backend)] = for { ref <- Resource.eval(Compat.ref(State.empty)) app = router(ref) diff --git a/project/Boilerplate.scala b/project/Boilerplate.scala new file mode 100644 index 000000000..534aa0326 --- /dev/null +++ b/project/Boilerplate.scala @@ -0,0 +1,345 @@ +import sbt._ +import scala.annotation.tailrec + +/** + * Copied, with some modifications, from https://github.com/milessabin/shapeless/blob/master/project/Boilerplate.scala + * + * Generate a range of boilerplate classes, those offering alternatives with 0-22 params + * and would be tedious to craft by hand + * + * @author Miles Sabin + * @author Kevin Wright + */ +object Boilerplate { + import scala.StringContext._ + + implicit final class BlockHelper(private val sc: StringContext) + extends AnyVal { + def block(args: Any*): String = { + val interpolated = sc.standardInterpolator(treatEscapes, args) + val rawLines = interpolated.split('\n') + val trimmedLines = rawLines.map(_.dropWhile(_.isWhitespace)) + trimmedLines.mkString("\n") + } + } + + sealed trait ScalaVersion + case object Scala2 extends ScalaVersion + case object Scala3 extends ScalaVersion + + sealed trait BoilerplateModule extends Product with Serializable + object BoilerplateModule { + case object Core extends BoilerplateModule + case object Core2 extends BoilerplateModule + case object Core3 extends BoilerplateModule + + def templates: Map[BoilerplateModule, List[Template]] = Map( + Core -> List(PartiallyAppliedStruct, PolyFunction), + Core2 -> List(Scala2Kinds, FunctorK(Scala2)), + Core3 -> List(Scala3Kinds, FunctorK(Scala3)) + ) + } + + /** + * Returns a seq of the generated files. As a side-effect, it actually generates them... + */ + def gen(dir: File, module: BoilerplateModule) = + for (t <- BoilerplateModule.templates(module)) yield { + val tgtFile = t.filename(dir) + IO.write(tgtFile, t.body) + tgtFile + } + + val maxArity = 22 + + final class TemplateVals(val arity: Int) { + val synTypes = (0 until arity).map(n => s"A$n") + val synVals = (0 until arity).map(n => s"a$n") + val synTypedVals = + (synVals.zip(synTypes)).map { case (v, t) => v + ":" + t } + val `A..N` = synTypes.mkString(", ") + val `a..n` = synVals.mkString(", ") + val `_.._` = Seq.fill(arity)("_").mkString(", ") + val `?..?` = Seq.fill(arity)("?").mkString(", ") + val `(A..N)` = + if (arity == 1) "Tuple1[A]" else synTypes.mkString("(", ", ", ")") + val `(_.._)` = + if (arity == 1) "Tuple1[_]" + else Seq.fill(arity)("_").mkString("(", ", ", ")") + val `(a..n)` = + if (arity == 1) "Tuple1(a)" else synVals.mkString("(", ", ", ")") + val `a:A..n:N` = synTypedVals.mkString(", ") + val `*` = IndexedSeq.fill(arity)("*").mkString(", ") + val `Any..Any` = IndexedSeq.fill(arity)("Any").mkString(", ") + } + + trait Template { + def filename(root: File): File + def content(tv: TemplateVals): String + def range: IndexedSeq[Int] = 1 to maxArity + + val copyright = + """/* + | * Copyright 2021-2022 Disney Streaming + | * + | * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); + | * you may not use this file except in compliance with the License. + | * You may obtain a copy of the License at + | * + | * https://disneystreaming.github.io/TOST-1.0.txt + | * + | * Unless required by applicable law or agreed to in writing, software + | * distributed under the License is distributed on an "AS IS" BASIS, + | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + | * See the License for the specific language governing permissions and + | * limitations under the License. + | */ + |""".stripMargin + + def clean(lines: List[String]): List[String] = lines.toList match { + case head1 :: head2 :: tl if (head1.isBlank() && head2.isBlank()) => + head1 :: tl + case head :: tl => head :: clean(tl) + case Nil => Nil + } + + def body: String = { + def expandInstances( + contents: IndexedSeq[Array[String]], + acc: Array[String] = Array.empty + ): Array[String] = + if (!contents.exists(_.exists(_.startsWith("-")))) + acc.map(_.tail) + else { + val pre = contents.head.takeWhile(_.startsWith("|")) + val instances = contents.flatMap( + _.dropWhile(_.startsWith("|")).takeWhile(_.startsWith("-")) + ) + val next = contents.map( + _.dropWhile(_.startsWith("|")).dropWhile(_.startsWith("-")) + ) + expandInstances(next, acc ++ pre ++ instances) + } + + val rawContents = range.map { n => + content(new TemplateVals(n)).split('\n').filterNot(_.isEmpty) + } + val headerLines = copyright.split('\n').toSeq ++ Seq( + "", + "/////// THIS FILE WAS GENERATED AT BUILD TIME, AND CHECKED-IN FOR DISCOVERABILITY ///////", + "" + ) + + val instances = expandInstances(rawContents) + val footerLines = rawContents.head.reverse + .takeWhile(_.startsWith("|")) + .map(_.tail) + .reverse + clean((headerLines ++ instances ++ footerLines).toList).mkString("\n") + } + } + + object PartiallyAppliedStruct extends Template { + override def filename(root: File): File = + root / "generated" / "schema" / "PartiallyAppliedStruct.scala" + + override def content(tv: TemplateVals): String = { + import tv._ + + val fields = synTypes.map { tpe => + s"Field[F, S, $tpe]" + } + + val schemaFields = synTypes.map { tpe => + s"SchemaField[S, $tpe]" + } + + val params = + synVals.zip(fields).map { case (v, t) => s"$v: $t" }.mkString(", ") + + val schemaParams = + synVals + .zip(schemaFields) + .map { case (v, t) => s"$v: $t" } + .mkString(", ") + + val args = synVals.mkString(", ") + + val consArgs = synVals.map(v => s"_$v").mkString(", ") + + val structMethods = + s"""def struct[S, ${`A..N`}]($params)(f: (${`A..N`}) => S): F[S]""" + + val casts = synTypes.zipWithIndex + .map { case (a, i) => + s"arr($i).asInstanceOf[${a}]" + } + .mkString(", ") + + val smartCtsr = + s"""def apply[${`A..N`}]($schemaParams)(const : (${`A..N`}) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector($args), arr => const($casts))""" + + block""" + |package smithy4s + |package schema + | + |class PartiallyAppliedStruct[S] protected[schema](placeholder: ShapeId) { + | + | def genericArity( + | fields: SchemaField[S, _]*)( + | const: IndexedSeq[Any] => S) : Schema[S] = + | Schema.StructSchema(placeholder, Hints.empty, fields.toVector, const) + | + | def apply( + | fields: Vector[SchemaField[S, _]])( + | const: IndexedSeq[Any] => S) : Schema[S] = + | Schema.StructSchema(placeholder, Hints.empty, fields, const) + | + - $smartCtsr + | + |} + """ + } + } + object PolyFunction extends Template { + override val range: IndexedSeq[Int] = IndexedSeq(1, 2, 5) + override def filename(root: File): File = + root / "generated" / "kinds" / "polyFunctions.scala" + override def content(tv: TemplateVals): String = { + import tv._ + + val suffix = if (arity == 1) "" else arity.toString() + + block""" + |package smithy4s + |package kinds + | + |import smithy4s.capability._ + | + -trait PolyFunction$suffix[F[${`_.._`}], G[${`_.._`}]]{ self => + - def apply[${`A..N`}](fa: F[${`A..N`}]): G[${`A..N`}] + - + - final def andThen[H[${`_.._`}]](other: PolyFunction$suffix[G, H]): PolyFunction$suffix[F, H] = new PolyFunction$suffix[F, H]{ + - def apply[${`A..N`}](fa: F[${`A..N`}]): H[${`A..N`}] = other(self(fa)) + - } + - + - import Kind$arity._ + - private[smithy4s] final def unsafeCacheBy[K](allPossibleInputs: Seq[Existential[F]], getKey: Existential[F] => K): PolyFunction$suffix[F, G] = + - new PolyFunction$suffix[F, G] { + - private val map: Map[K, Any] = { + - val builder = Map.newBuilder[K, Any] + - allPossibleInputs.foreach(input => + - builder += getKey(input) -> self + - .apply(input.asInstanceOf[F[${`Any..Any`}]]) + - .asInstanceOf[Any] + - ) + - builder.result() + - } + - def apply[${`A..N`}](input: F[${`A..N`}]): G[${`A..N`}] = map(getKey(existential(input))).asInstanceOf[G[${`A..N`}]] + - } + -} + -object PolyFunction$suffix{ + - type From[F[${`_.._`}]] = { + - type Algebra[G[${`_.._`}]] = PolyFunction$suffix[F, G] + - } + - + - def identity[F[${`_.._`}]] : PolyFunction$suffix[F, F] = new PolyFunction$suffix[F, F]{ + - def apply[${`A..N`}](input: F[${`A..N`}]): F[${`A..N`}] = input + - } + - + - implicit def polyfunction${suffix}_transformation[Alg[_[${`_.._`}]]: FunctorK$suffix, F[${`_.._`}], G[${`_.._`}]]: Transformation[PolyFunction$suffix[F, G], Alg[F], Alg[G]] = + - new Transformation[PolyFunction$suffix[F, G], Alg[F], Alg[G]]{ + - def apply(func: PolyFunction$suffix[F, G], algF: Alg[F]) : Alg[G] = FunctorK$suffix[Alg].mapK$suffix(algF, func) + - } + -} + - + - + | + """ + } + } + + case class FunctorK(scalaVersion: ScalaVersion) extends Template { + override val range: IndexedSeq[Int] = IndexedSeq(1, 2, 5) + override def filename(root: File): File = + root / "generated" / "kinds" / "functorK.scala" + override def content(tv: TemplateVals): String = { + import tv._ + + val suffix = if (arity == 1) "" else arity.toString() + + val functorKSig = scalaVersion match { + case Scala2 => s"FunctorK$suffix[PolyFunction$suffix[F, *[${`_.._`}]]]" + case Scala3 => + s"FunctorK$suffix[[G[${`_.._`}]] =>> PolyFunction$suffix[F, G]]" + } + + val inline = scalaVersion match { + case Scala2 => "@inline" + case Scala3 => "inline" + } + + block""" + |package smithy4s + |package kinds + | + -trait FunctorK$suffix[Alg[_[${`_.._`}]]]{ + - def mapK$suffix[F[${`_.._`}], G[${`_.._`}]](alg: Alg[F], function: PolyFunction$suffix[F, G]): Alg[G] + -} + -object FunctorK$suffix { + - $inline def apply[Alg[_[${`_.._`}]]](implicit ev: FunctorK$suffix[Alg]) : FunctorK$suffix[Alg] = ev + - + - implicit def polyfunctionFunctorK$suffix[F[${`_.._`}]]: $functorKSig = new $functorKSig { + - def mapK$suffix[G[${`_.._`}], H[${`_.._`}]](fa: PolyFunction$suffix[F, G], fk: PolyFunction$suffix[G, H]): PolyFunction$suffix[F, H] = fa.andThen(fk) + - } + -} + - + """ + } + } + + object Scala3Kinds extends Template { + override val range: IndexedSeq[Int] = IndexedSeq(1, 2, 5) + override def filename(root: File): File = + root / "generated" / "kinds" / "kinds.scala" + override def content(tv: TemplateVals): String = { + import tv._ + + val suffix = if (arity == 1) "" else arity.toString() + + block""" + |package smithy4s + |package kinds + | + -object Kind$arity{ + - type Existential[+F[${`_.._`}]] <: (Any { type T }) + - inline def existential[F[${`_.._`}], ${`A..N`}](fa: F[${`A..N`}]): Existential[F] = fa.asInstanceOf[Existential[F]] + -} + - + """ + } + } + + object Scala2Kinds extends Template { + override val range: IndexedSeq[Int] = IndexedSeq(1, 2, 5) + override def filename(root: File): File = + root / "generated" / "kinds" / "kinds.scala" + override def content(tv: TemplateVals): String = { + import tv._ + + val suffix = if (arity == 1) "" else arity.toString() + + block""" + |package smithy4s + |package kinds + | + -object Kind$arity{ + - type Existential[F[${`_.._`}]] = F[${`_.._`}] + - @inline def existential[F[${`_.._`}], ${`A..N`}](fa: F[${`A..N`}]): F[${`_.._`}] = fa.asInstanceOf[F[${`_.._`}]] + -} + - + """ + } + } + +} diff --git a/project/SchematicBoilerplate.scala b/project/SchematicBoilerplate.scala deleted file mode 100644 index 41cab17e5..000000000 --- a/project/SchematicBoilerplate.scala +++ /dev/null @@ -1,189 +0,0 @@ -import sbt._ -import scala.annotation.tailrec - -/** - * Copied, with some modifications, from https://github.com/milessabin/shapeless/blob/master/project/Boilerplate.scala - * - * Generate a range of boilerplate classes, those offering alternatives with 0-22 params - * and would be tedious to craft by hand - * - * @author Miles Sabin - * @author Kevin Wright - */ -object Boilerplate { - import scala.StringContext._ - - implicit final class BlockHelper(private val sc: StringContext) - extends AnyVal { - def block(args: Any*): String = { - val interpolated = sc.standardInterpolator(treatEscapes, args) - val rawLines = interpolated.split('\n') - val trimmedLines = rawLines.map(_.dropWhile(_.isWhitespace)) - trimmedLines.mkString("\n") - } - } - - sealed trait BoilerplateModule extends Product with Serializable - object BoilerplateModule { - case object Core extends BoilerplateModule - - def templates: Map[BoilerplateModule, List[Template]] = Map( - Core -> List(PartiallyAppliedStruct) - ) - } - - /** - * Returns a seq of the generated files. As a side-effect, it actually generates them... - */ - def gen(dir: File, module: BoilerplateModule) = - for (t <- BoilerplateModule.templates(module)) yield { - val tgtFile = t.filename(dir) - IO.write(tgtFile, t.body) - tgtFile - } - - val maxArity = 22 - - final class TemplateVals(val arity: Int) { - val synTypes = (0 until arity).map(n => s"A$n") - val synVals = (0 until arity).map(n => s"a$n") - val synTypedVals = - (synVals.zip(synTypes)).map { case (v, t) => v + ":" + t } - val `A..N` = synTypes.mkString(", ") - val `a..n` = synVals.mkString(", ") - val `_.._` = Seq.fill(arity)("_").mkString(", ") - val `(A..N)` = - if (arity == 1) "Tuple1[A]" else synTypes.mkString("(", ", ", ")") - val `(_.._)` = - if (arity == 1) "Tuple1[_]" - else Seq.fill(arity)("_").mkString("(", ", ", ")") - val `(a..n)` = - if (arity == 1) "Tuple1(a)" else synVals.mkString("(", ", ", ")") - val `a:A..n:N` = synTypedVals.mkString(", ") - } - - trait Template { - def filename(root: File): File - def content(tv: TemplateVals): String - def range = 1 to maxArity - - val copyright = """/* - | * Copyright 2021-2022 Disney Streaming - | * - | * Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License"); - | * you may not use this file except in compliance with the License. - | * You may obtain a copy of the License at - | * - | * https://disneystreaming.github.io/TOST-1.0.txt - | * - | * Unless required by applicable law or agreed to in writing, software - | * distributed under the License is distributed on an "AS IS" BASIS, - | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - | * See the License for the specific language governing permissions and - | * limitations under the License. - | */ - |""".stripMargin - - def clean(lines: List[String]): List[String] = lines.toList match { - case head1 :: head2 :: tl if (head1.isBlank() && head2.isBlank()) => - head1 :: tl - case head :: tl => head :: clean(tl) - case Nil => Nil - } - - def body: String = { - def expandInstances( - contents: IndexedSeq[Array[String]], - acc: Array[String] = Array.empty - ): Array[String] = - if (!contents.exists(_.exists(_.startsWith("-")))) - acc.map(_.tail) - else { - val pre = contents.head.takeWhile(_.startsWith("|")) - val instances = contents.flatMap( - _.dropWhile(_.startsWith("|")).takeWhile(_.startsWith("-")) - ) - val next = contents.map( - _.dropWhile(_.startsWith("|")).dropWhile(_.startsWith("-")) - ) - expandInstances(next, acc ++ pre ++ instances) - } - - val rawContents = range.map { n => - content(new TemplateVals(n)).split('\n').filterNot(_.isEmpty) - } - val headerLines = copyright.split('\n').toSeq ++ Seq("") - - val instances = expandInstances(rawContents) - val footerLines = rawContents.head.reverse - .takeWhile(_.startsWith("|")) - .map(_.tail) - .reverse - clean((headerLines ++ instances ++ footerLines).toList).mkString("\n") - } - } - - object PartiallyAppliedStruct extends Template { - override def filename(root: File): File = - root / "generated" / "PartiallyAppliedStruct.scala" - - override def content(tv: TemplateVals): String = { - import tv._ - - val fields = synTypes.map { tpe => - s"Field[F, S, $tpe]" - } - - val schemaFields = synTypes.map { tpe => - s"SchemaField[S, $tpe]" - } - - val params = - synVals.zip(fields).map { case (v, t) => s"$v: $t" }.mkString(", ") - - val schemaParams = - synVals - .zip(schemaFields) - .map { case (v, t) => s"$v: $t" } - .mkString(", ") - - val args = synVals.mkString(", ") - - val consArgs = synVals.map(v => s"_$v").mkString(", ") - - val structMethods = - s"""def struct[S, ${`A..N`}]($params)(f: (${`A..N`}) => S): F[S]""" - - val casts = synTypes.zipWithIndex - .map { case (a, i) => - s"arr($i).asInstanceOf[${a}]" - } - .mkString(", ") - - val smartCtsr = - s"""def apply[${`A..N`}]($schemaParams)(const : (${`A..N`}) => S) : Schema[S] = Schema.StructSchema[S](placeholder, Hints.empty, Vector($args), arr => const($casts))""" - - block""" - |package smithy4s - |package schema - | - |class PartiallyAppliedStruct[S] protected[schema](placeholder: ShapeId) { - | - | def genericArity( - | fields: SchemaField[S, _]*)( - | const: IndexedSeq[Any] => S) : Schema[S] = - | Schema.StructSchema(placeholder, Hints.empty, fields.toVector, const) - | - | def apply( - | fields: Vector[SchemaField[S, _]])( - | const: IndexedSeq[Any] => S) : Schema[S] = - | Schema.StructSchema(placeholder, Hints.empty, fields, const) - | - - $smartCtsr - | - |} - """ - } - } - -} diff --git a/project/Smithy4sPlugin.scala b/project/Smithy4sPlugin.scala index 1ff678450..b5a7db3a1 100644 --- a/project/Smithy4sPlugin.scala +++ b/project/Smithy4sPlugin.scala @@ -160,7 +160,12 @@ object Smithy4sPlugin extends AutoPlugin { val base = if (scalaVersion.startsWith("3.")) filterScala3Options(commonCompilerOptions) - else commonCompilerOptions + else + commonCompilerOptions + // ++ Seq( + // "-Xsource:3", + // "-P:kind-projector:underscore-placeholders" + // ) base ++ targetScalacOptions(scalaVersion) ++ { if (priorTo2_13(scalaVersion)) compilerOptions2_12_Only