in http-server/src/main/scala/com/twitter/finatra/http/internal/routing/CallbackConverter.scala [57:109]
private def createRequestCallback[RequestType: TypeTag, ResponseType: TypeTag](
callback: RequestType => ResponseType
): Request => ResponseType = {
val manifestRequestType = TypeUtils.asManifest[RequestType]
manifestRequestType match {
case request if request == manifest[Request] =>
callback.asInstanceOf[Request => ResponseType]
case streamingRequest if runtimeClassEqs[StreamingRequest[Any, _]](streamingRequest) =>
val streamIdentity = streamingRequest.typeArguments.head
val streamType = streamingRequest.typeArguments.last
request: Request =>
// Cannot assign StreamingRequest result to a value because 2.13 treats these abstractions over HKTs as errors
streamIdentity match {
case reader if runtimeClassEqs[Reader[_]](reader) =>
callback(
StreamingRequest(jsonStreamParser, request)(FromReader.ReaderIdentity, streamType)
.asInstanceOf[RequestType])
case asyncStream if runtimeClassEqs[AsyncStream[_]](asyncStream) =>
callback(
StreamingRequest
.fromRequestToAsyncStream(jsonStreamParser, request)(streamType)
.asInstanceOf[RequestType])
case _ =>
throw new Exception(
s"Unsupported StreamingRequest type detected as $streamIdentity"
)
}
case asyncStream if runtimeClassEqs[AsyncStream[_]](asyncStream) =>
val asyncStreamTypeParam = asyncStream.typeArguments.head
request: Request =>
val asyncStream = jsonStreamParser.parseArray(request.reader)(asyncStreamTypeParam)
callback(asyncStream.asInstanceOf[RequestType])
case reader if runtimeClassEqs[Reader[_]](reader) =>
val readerTypeParam = reader.typeArguments.head
request: Request =>
val reader = jsonStreamParser.parseJson(request.reader)(readerTypeParam)
callback(reader.asInstanceOf[RequestType])
case intOrString
if runtimeClassEqs[Int](intOrString) || runtimeClassEqs[String](intOrString) =>
// NOTE: callback functions with no input param which return a String are inferred as a RequestType of
// `Int` by Scala because `StringOps.apply` is a function of Int => Char, other return types
// infer a `RequestType` of `String`.
throw new Exception(
s"Improper callback function RequestType: ${manifestRequestType.runtimeClass}. Controller routes defined with a callback function that has no input parameter or with an incorrectly specified input parameter type are not allowed. " +
s"Please specify an input parameter in your route callback function of the appropriate type. For more details see: $url"
)
case _ =>
request: Request =>
val callbackInput = messageBodyManager.read[RequestType](request)
callback(callbackInput)
}
}