Skip to content

Instantly share code, notes, and snippets.

@ovechkin-dm
Last active July 19, 2019 13:51
Show Gist options
  • Save ovechkin-dm/fc28dc4f6e9bc5a9f6180ed3e83f9d4d to your computer and use it in GitHub Desktop.
Save ovechkin-dm/fc28dc4f6e9bc5a9f6180ed3e83f9d4d to your computer and use it in GitHub Desktop.
package demo
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives.{complete, pathPrefix}
import akka.http.scaladsl.server.Route
import akka.stream.ActorMaterializer
import monix.execution.Scheduler
import ru.tinkoff.tschema.akkaHttp.{MkRoute, RoutableIn, Serve}
import ru.tinkoff.tschema.swagger.Tag
import ru.tinkoff.tschema.syntax.{operation, queryParam, tagPrefix, _}
import shapeless.{::, HList, HNil, Witness}
object Example {
implicit val system = ActorSystem()
implicit val mat = ActorMaterializer()
implicit val scheduler = Scheduler.Implicits.global
trait AnyOp {
implicit def anyCons[H, T <: HList](implicit t: Op[T]): Op[H :: T] = h => t.apply(h.tail)
}
object Op extends AnyOp {
implicit val emptyOp: Op[HNil] = _ => ()
implicit def methodCapture[name <: Symbol, L <: HList](implicit w: Witness.Aux[name],
op: Op[L]): Op[Serve.key[name] :: L] =
new Op[Serve.key[name] :: L] { l =>
override def apply(h: Serve.key[name] :: L): Unit = {
println(s"captured method: ${w.value.name}")
op.apply(h.tail)
}
}
implicit def tagCapture[name <: Symbol, L <: HList](implicit w: Witness.Aux[name], op: Op[L]): Op[Tag[name] :: L] =
new Op[Tag[name] :: L] { l =>
override def apply(h: Tag[name] :: L): Unit = {
println(s"captured tag: ${w.value.name}") // not reachable
op.apply(h.tail)
}
}
}
implicit def routableIn[In <: HList](implicit op: Op[In]): RoutableIn[In, SimpleValue, SimpleValue] = { (in, res) =>
{
op(in)
complete(res.s)
}
}
val route: Route =
pathPrefix("api") {
MkRoute(api)(service)
}
def api = tagPrefix('hello) |> (
operation('getValue) |>
get |>
queryParam[String]('param) |>
$$[SimpleValue]
)
object service {
def getValue(param: String): SimpleValue = {
SimpleValue(param)
}
}
trait Op[H <: HList] {
def apply(h: H): Unit
}
def main(args: Array[String]): Unit = {
Http().bindAndHandle(route, "localhost", 8081)
}
case class SimpleValue(s: String)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment