Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ShapeId a datatype #25

Merged
merged 7 commits into from
Jan 5, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions modules/aws-kernel/src/smithy4s/aws/AwsRegion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ import smithy4s.Newtype

object AwsRegion extends Newtype[String] {

val namespace = "smithy4s.aws"
val name = "AwsRegion"
val id = smithy4s.ShapeId("smithy4s.aws", "AwsRegion")

val AF_SOUTH_1: AwsRegion = apply("af-south-1")
val AP_EAST_1: AwsRegion = apply("ap-east-1")
Expand Down
4 changes: 2 additions & 2 deletions modules/aws/src/smithy4s/aws/AwsClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ object AwsClient {
awsService <- service.hints
.get(_root_.aws.api.Service)
.liftTo[Resource[F, *]](
initError(s"${service.identifier} is not an AWS service")
initError(s"${service.id.show} is not an AWS service")
)
endpointPrefix <- awsService.endpointPrefix.liftTo[Resource[F, *]](
initError(s"No endpoint prefix for $awsService")
)
awsProtocol <- AwsProtocol(service.hints).liftTo[Resource[F, *]](
initError(
s"AWS protocol used by ${service.identifier} is not yet supported"
s"AWS protocol used by ${service.id.show} is not yet supported"
)
)
} yield service.transform(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private[aws] class AwsJsonRPCInterpreter[Alg[_[_, _, _, _, _]], Op[_,_,_,_,_], F
}

private val signer: AwsSigner[F] = AwsSigner.rpcSigner[F](
service,
service.id,
endpointPrefix,
awsEnv,
contentType
Expand Down
6 changes: 3 additions & 3 deletions modules/aws/src/smithy4s/aws/internals/AwsSigner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ package internals

import cats.Monad
import cats.syntax.all._
import smithy4s.HasId
import smithy4s.aws.kernel.AwsSignature
import smithy4s.http.CaseInsensitive
import smithy4s.http.HttpMethod
import smithy4s.http.Metadata
import smithy4s.ShapeId

private[aws] trait AwsSigner[F[_]] {
def sign(
Expand All @@ -38,15 +38,15 @@ object AwsSigner {
private[aws] val EMPTY_PATH = "/"

private[aws] def rpcSigner[F[_]: Monad](
serviceId: HasId,
serviceId: ShapeId,
endpointPrefix: String,
environment: AwsEnvironment[F],
contentType: String
): AwsSigner[F] =
new RPCSigner[F](serviceId, endpointPrefix, environment, contentType)

private class RPCSigner[F[_]: Monad](
serviceId: HasId,
serviceId: ShapeId,
endpointPrefix: String,
awsEnv: AwsEnvironment[F],
contentType: String
Expand Down
3 changes: 3 additions & 0 deletions modules/codegen/src/smithy4s/codegen/CollisionAvoidance.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ object CollisionAvoidance {
val newOps = ops.map {
case Operation(
name,
ns,
params,
input,
errors,
Expand All @@ -41,6 +42,7 @@ object CollisionAvoidance {
) =>
Operation(
protect(name.capitalize),
ns,
params.map(modField),
modType(input),
errors.map(modType),
Expand Down Expand Up @@ -224,6 +226,7 @@ object CollisionAvoidance {
val Service_ = "smithy4s.Service"
val Endpoint_ = "smithy4s.Endpoint"
val NoInput_ = "smithy4s.NoInput"
val ShapeId_ = "smithy4s.ShapeId"
val Schema_ = "smithy4s.Schema"
val StreamingSchema_ = "smithy4s.StreamingSchema"
val Enumeration_ = "smithy4s.Enumeration"
Expand Down
1 change: 1 addition & 0 deletions modules/codegen/src/smithy4s/codegen/IR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ case class Service(

case class Operation(
name: String,
originalNamespace: String,
params: List[Field],
input: Type,
errors: List[Type],
Expand Down
27 changes: 12 additions & 15 deletions modules/codegen/src/smithy4s/codegen/Renderer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,6 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self =>
block(
s"package object ${compilationUnit.namespace.split('.').last}"
)(
line(s"""val NAMESPACE: String = "${compilationUnit.namespace}""""),
newline,
compilationUnit.declarations.map(renderDeclPackageContents),
newline,
typeAliases,
Expand All @@ -117,8 +115,7 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self =>
)(
s"def apply[F[_]](implicit F: $name[F]): F.type = F",
s"def service : smithy4s.Service[${name}Gen, ${name}Operation] = ${name}Gen",
s"def namespace: String = service.namespace",
s"def name: String = service.name"
s"val id: $ShapeId_ = service.id"
)
)
case _ => empty
Expand Down Expand Up @@ -167,12 +164,12 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self =>
s"def apply[F[_]](implicit F: smithy4s.Monadic[$genName, F]): F.type = F"
),
newline,
renderId(originalName),
newline,
renderHintsVal(hints),
newline,
line(s"val endpoints = List").args(ops.map(_.name)),
newline,
line(s"""def namespace: String = "$namespace""""),
line(s"""val name: String = "$originalName""""),
line(s"""val version: String = "$version""""),
newline,
if (ops.isEmpty) {
Expand Down Expand Up @@ -288,6 +285,7 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self =>
s"val output: $Schema_[${op.output.render}] = ${op.output.schemaRef}.withHints(smithy4s.internals.InputOutput.Output)",
renderStreamingSchemaVal("streamedInput", op.streamedInput),
renderStreamingSchemaVal("streamedOutput", op.streamedOutput),
renderId(op.name, op.originalNamespace),
renderHintsVal(op.hints),
s"def wrap(input: ${op.input.render}) = ${opName}($input)",
renderErrorable(op),
Expand Down Expand Up @@ -346,8 +344,7 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self =>
}
} else line(decl),
obj(name, ext = hintKey(name, hints))(
line(s"""def namespace: String = NAMESPACE"""),
line(s"""val name: String = "$name""""),
renderId(name),
newline,
renderHintsVal(hints),
newline,
Expand Down Expand Up @@ -450,8 +447,7 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self =>
lines(
s"sealed trait $name",
obj(name, ext = hintKey(name, hints))(
line(s"""def namespace: String = NAMESPACE"""),
line(s"""val name: String = "$name""""),
renderId(name),
newline,
renderHintsVal(hints),
newline,
Expand Down Expand Up @@ -508,8 +504,7 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self =>
): RenderResult = lines(
s"sealed abstract class $name(val value: String, val ordinal: Int) extends Product with Serializable",
obj(name, ext = s"$Enumeration_[$name]", w = hintKey(name, hints))(
line(s"""def namespace: String = NAMESPACE"""),
line(s"""val name: String = "$name""""),
renderId(name),
newline,
values.zipWithIndex.map { case (e @ EnumValue(value, _, _), index) =>
line(
Expand Down Expand Up @@ -553,8 +548,7 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self =>
s"implicit val staticSchema : $Static_[$Schema_[${tpe.render}]] = $Static_(schema)"
),
lines(
line("def namespace = NAMESPACE"),
line(s"""val name = "${name}""""),
renderId(name),
hintsRef,
s"val schema : $Schema_[$name] = bijection(T.schema, $name(_), (_ : $name).value)",
s"implicit val staticSchema : $Static_[$Schema_[$name]] = $Static_(schema)"
Expand Down Expand Up @@ -693,9 +687,12 @@ private[codegen] class Renderer(compilationUnit: CompilationUnit) { self =>
case _ => None
}

def renderId(name: String, ns: String = namespace): RenderResult =
line(s"""val id: $ShapeId_ = $ShapeId_("$ns", "$name")""")

def renderHintsVal(hints: List[Hint]): RenderResult =
line(s"val hints : $Hints_ = $Hints_").args {
hints.flatMap(renderHint(_).toList)
"id" :: hints.flatMap(renderHint(_).toList)
}

def memberHints(hints: List[Hint]): String = {
Expand Down
1 change: 1 addition & 0 deletions modules/codegen/src/smithy4s/codegen/SmithyToIR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ private[codegen] class SmithyToIR(model: Model, namespace: String) {

Operation(
op.name,
op.namespace,
params,
inputType,
errorTypes,
Expand Down
19 changes: 9 additions & 10 deletions modules/core/src-2/Hints.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ package smithy4s
*/
trait Hints {
def isEmpty: Boolean
def all: Seq[Hints.Binding[_]]
def toMap: Map[Hints.Key[_], Hint]
def all: Iterable[Hints.Binding[_]]
def get[A](implicit key: Hints.Key[A]): Option[A]
final def get[A](key: Hints.Key.Has[A]): Option[A] = get(key.getKey)
final def get[T](nt: Newtype[T]): Option[nt.Type] = get(nt.key)
Expand All @@ -38,7 +39,7 @@ trait Hints {
object Hints {

def apply[S](bindings: Hint*): Hints = {
new Impl(bindings, bindings.map(_.tuple: (Key[_], Hint)).toMap)
new Impl(bindings.map(_.tuple: (Key[_], Hint)).toMap)
}

trait Schematic[F[_]] {
Expand Down Expand Up @@ -79,21 +80,19 @@ object Hints {
}

private[smithy4s] class Impl(
bindings: Seq[Hint],
map: Map[Key[_], Hint]
val toMap: Map[Key[_], Hint]
) extends Hints {
val isEmpty = bindings.isEmpty
val all: Seq[Hint] = bindings
val isEmpty = toMap.isEmpty
def all: Iterable[Hint] = toMap.values
def get[A](implicit key: Key[A]): Option[A] =
map.get(key).map { case Binding(_, value) =>
toMap.get(key).map { case Binding(_, value) =>
value.asInstanceOf[A]
}
def ++(other: Hints): Hints = {
val b = bindings ++ other.all
new Impl(b, b.map(_.tuple: (Key[_], Hint)).toMap)
new Impl(toMap ++ other.toMap)
}
override def toString(): String =
s"Hints(${bindings.map(_.value).mkString(", ")})"
s"Hints(${all.map(_.value).mkString(", ")})"
}

case class Binding[A](key: Key[A], value: A) {
Expand Down
3 changes: 1 addition & 2 deletions modules/core/src-2/Newtype.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ abstract class Newtype[A] extends HasId { self =>
}

implicit val key: Hints.Key[Type] = new Hints.Key[Type] {
def namespace: String = self.namespace
def name: String = self.name
def id: ShapeId = self.id
}

def unapply(t: Type): Some[A] = Some(t.value)
Expand Down
25 changes: 13 additions & 12 deletions modules/core/src-3/Hints.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ package smithy4s
*/
trait Hints {
def isEmpty: Boolean
def all: Seq[Hints.Binding[_]]
def toMap: Map[Hints.Key[_], Hint]
def all: Iterable[Hints.Binding[_]]
def get[A](implicit key: Hints.Key[A]): Option[A]
final def get[A](key: Hints.Key.Has[A]): Option[A] = get(key.getKey)
final def get[T](nt: Newtype[T]): Option[nt.Type] = get(nt.key)
Expand All @@ -38,7 +39,7 @@ trait Hints {
object Hints {

def apply[S](bindings: Hint*): Hints = {
new Impl(bindings, bindings.map(_.tuple: (Key[_], Hint)).toMap)
new Impl(bindings.map(_.tuple: (Key[_], Hint)).toMap)
}

trait Schematic[F[_]] {
Expand Down Expand Up @@ -81,19 +82,19 @@ object Hints {
}

private[smithy4s] class Impl(
bindings: Seq[Hint],
map: Map[Key[_], Hint]
val toMap: Map[Key[_], Hint]
) extends Hints {
val isEmpty = bindings.isEmpty
val all: Seq[Hint] = bindings
def get[A](implicit key: Key[A]): Option[A] = map.get(key).map {
case Binding(_, value) => value.asInstanceOf[A]
}
val isEmpty = toMap.isEmpty
def all: Iterable[Hint] = toMap.values
def get[A](implicit key: Key[A]): Option[A] =
toMap.get(key).map { case Binding(_, value) =>
value.asInstanceOf[A]
}
def ++(other: Hints): Hints = {
val b = bindings ++ other.all
new Impl(b, b.map(_.tuple: (Key[_], Hint)).toMap)
new Impl(toMap ++ other.toMap)
}
override def toString(): String = "Hints(...)"
override def toString(): String =
s"Hints(${all.map(_.value).mkString(", ")})"
}

case class Binding[A](key: Key[A], value: A) {
Expand Down
3 changes: 1 addition & 2 deletions modules/core/src-3/Newtype.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ abstract class Newtype[A] extends HasId { self =>
def unapply(orig: Type): Some[A] = Some(orig.value)

implicit val key: Hints.Key[Type] = new Hints.Key[Type] {
def namespace: String = self.namespace
def name: String = self.name
def id: ShapeId = self.id
}

}
4 changes: 1 addition & 3 deletions modules/core/src/smithy4s/HasId.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,5 @@
package smithy4s

trait HasId {
def namespace: String
def name: String
def identifier: String = namespace + '.' + name
def id: ShapeId
}
26 changes: 26 additions & 0 deletions modules/core/src/smithy4s/ShapeId.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2021 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

case class ShapeId(namespace: String, name: String) {
def show = s"$namespace#$name"
override def toString = show
}

object ShapeId extends Hints.Key.Companion[ShapeId] {
def id: ShapeId = ShapeId("smithy4s", "ShapeId")
}
2 changes: 1 addition & 1 deletion modules/core/src/smithy4s/UnsupportedProtocolError.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ package smithy4s
final case class UnsupportedProtocolError(service: HasId, protocolKey: HasId)
extends Throwable {
override def getMessage(): String =
s"Service ${service.identifier} does not support the ${protocolKey.identifier} protocol"
s"Service ${service.id.show} does not support the ${protocolKey.id.show} protocol"
}
3 changes: 1 addition & 2 deletions modules/core/src/smithy4s/http/HttpBinding.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ sealed abstract class HttpBinding(val tpe: HttpBinding.Type)

object HttpBinding extends Hints.Key.Companion[HttpBinding] {

def namespace: String = "smithy4s.http"
def name: String = "HttpBinding"
val id: ShapeId = ShapeId("smithy4s.http", "HttpBinding")

sealed trait Type
object Type {
Expand Down
3 changes: 1 addition & 2 deletions modules/core/src/smithy4s/http/HttpMediaType.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,5 @@ package smithy4s.http
import smithy4s.Newtype

object HttpMediaType extends Newtype[String] {
def namespace: String = "smithy4s.http"
def name: String = "HttpBinding"
def id: smithy4s.ShapeId = smithy4s.ShapeId("smithy4s.http", "HttpMediaType")
}
3 changes: 1 addition & 2 deletions modules/core/src/smithy4s/internals/InputOutput.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ sealed trait InputOutput

object InputOutput extends Hints.Key.Companion[InputOutput] {

def namespace: String = "smithy4s"
def name: String = "InputOuput"
def id: ShapeId = ShapeId("smithy4s", "InputOutput")

case object Input extends InputOutput
case object Output extends InputOutput
Expand Down
Loading