-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #68 from kubukoz/stdlib
- Loading branch information
Showing
8 changed files
with
192 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
std.smithy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../smithy/std.smithy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package playground | ||
|
||
import cats.MonadThrow | ||
import cats.implicits._ | ||
import smithy4s.Document | ||
import smithy4s.Endpoint | ||
import smithy4s.Service | ||
import smithy4s.schema.Schema | ||
|
||
class DynamicServiceProxy[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _]]( | ||
service: Service[Alg, Op] | ||
) { | ||
|
||
def tryProxy[AlgStatic[_[_, _, _, _, _]], OpStatic[_, _, _, _, _], F[_]: MonadThrow]( | ||
interp: smithy4s.Monadic[AlgStatic, F] | ||
)( | ||
implicit serviceStatic: Service[AlgStatic, OpStatic] | ||
): Option[smithy4s.Interpreter[Op, F]] = | ||
Option.when(service.id == serviceStatic.id)(proxy(interp)(serviceStatic)) | ||
|
||
def proxy[AlgStatic[_[_, _, _, _, _]], OpStatic[_, _, _, _, _], F[_]: MonadThrow]( | ||
interp: smithy4s.Monadic[AlgStatic, F] | ||
)( | ||
serviceStatic: Service[AlgStatic, OpStatic] | ||
): smithy4s.Interpreter[Op, F] = { | ||
val grp = serviceStatic.endpoints.groupBy(_.id).fmap(_.head) | ||
|
||
type Proxy[I, E, O, SE, EO] = I => F[O] | ||
|
||
def makeProxy[A, B](schemaIn: Schema[A], schemaOut: Schema[B]): A => F[B] = { | ||
val inputEncoder = Document.Encoder.fromSchema(schemaIn) | ||
val outputDecoder = Document.Decoder.fromSchema(schemaOut) | ||
|
||
in => outputDecoder.decode(inputEncoder.encode(in)).liftTo[F] | ||
} | ||
|
||
val endpointMapping = | ||
new (smithy4s.Transformation[Endpoint[Op, *, *, *, *, *], Proxy]) { | ||
private val trans = serviceStatic.asTransformation(interp) | ||
|
||
private def applyWithStatic[I, E, O, SI, SO, STI, STE, STO, STSI, STSO]( | ||
endpoint: Endpoint[Op, I, E, O, SI, SO], | ||
endpointStatic: Endpoint[OpStatic, STI, STE, STO, STSI, STSO], | ||
): I => F[O] = { | ||
val mapInput = makeProxy(endpoint.input, endpointStatic.input) | ||
val mapOutput = makeProxy(endpointStatic.output, endpoint.output) | ||
|
||
def errorMapper[A]: Throwable => F[A] = | ||
endpointStatic.errorable match { | ||
case None => _.raiseError[F, A] | ||
case Some(errorableStatic) => | ||
val errorable = endpoint.errorable.get // should be there at this point | ||
val mapError = makeProxy(errorableStatic.error, errorable.error) | ||
|
||
e => | ||
errorableStatic.liftError(e) match { | ||
case None => e.raiseError[F, A] | ||
case Some(liftedStatic) => | ||
mapError(liftedStatic) | ||
.flatMap(errorable.unliftError(_).raiseError[F, A]) | ||
} | ||
} | ||
|
||
input => | ||
mapInput(input) | ||
.map(endpointStatic.wrap) | ||
.flatMap(trans(_)) | ||
.handleErrorWith(errorMapper) | ||
.flatMap(mapOutput) | ||
} | ||
|
||
def apply[I, E, O, SI, SO](endpoint: Endpoint[Op, I, E, O, SI, SO]): I => F[O] = | ||
applyWithStatic(endpoint, grp(endpoint.id)) | ||
} | ||
.precompute(service.endpoints) | ||
|
||
new smithy4s.Interpreter[Op, F] { | ||
def apply[I, E, O, SI, SO](op: Op[I, E, O, SI, SO]): F[O] = { | ||
val (input, endpoint) = service.endpoint(op) | ||
endpointMapping(endpoint)(input) | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package playground.std | ||
|
||
import cats.Functor | ||
import cats.effect.std.UUIDGen | ||
import cats.implicits._ | ||
import smithy4s.Timestamp | ||
|
||
trait StdlibRuntime[F[_]] { | ||
def random: Random[F] | ||
def clock: Clock[F] | ||
} | ||
|
||
object StdlibRuntime { | ||
def apply[F[_]](implicit F: StdlibRuntime[F]): StdlibRuntime[F] = F | ||
|
||
def instance[F[_]: cats.effect.Clock: UUIDGen: Functor]: StdlibRuntime[F] = | ||
new StdlibRuntime[F] { | ||
|
||
val random: Random[F] = | ||
new playground.std.Random[F] { | ||
def nextUUID(): F[NextUUIDOutput] = UUIDGen[F].randomUUID.map(NextUUIDOutput(_)) | ||
} | ||
|
||
val clock: Clock[F] = | ||
new Clock[F] { | ||
|
||
def currentTimestamp( | ||
): F[CurrentTimestampOutput] = cats | ||
.effect | ||
.Clock[F] | ||
.realTimeInstant | ||
.map(Timestamp.fromInstant) | ||
.map(CurrentTimestampOutput.apply) | ||
|
||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
namespace playground.std | ||
use smithy4s.api#UUID | ||
|
||
@trait(selector: "service") | ||
@protocolDefinition | ||
structure stdlib {} | ||
|
||
@stdlib | ||
service Random { | ||
operations: [NextUUID] | ||
} | ||
|
||
operation NextUUID { | ||
output: NextUUIDOutput | ||
} | ||
|
||
structure NextUUIDOutput { | ||
@required | ||
value: UUID | ||
} | ||
|
||
@stdlib | ||
service Clock { | ||
operations: [CurrentTimestamp] | ||
} | ||
|
||
operation CurrentTimestamp { | ||
output: CurrentTimestampOutput | ||
} | ||
|
||
structure CurrentTimestampOutput { | ||
@required | ||
value: Timestamp | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters