I need to implement Ad-hoc polymorphism, consider this code:
trait BlockInputRequest
case class StaticBlockInput(
content: String
) extends BlockInputRequest
case class StaticBlockOutput(
content: String = ""
)
trait BlockProcessor[T] {
def processBlock(request: T, project: String, userEmail: String, empty: Boolean = false)(implicit ec: ExecutionContext): Future[Any]
}
implicit val StaticBlockInputProcessor: BlockProcessor[StaticBlockInput] = new BlockProcessor[StaticBlockInput] {
override def processBlock(request: StaticBlockInput, project: String, userEmail: String, empty: Boolean)(implicit ec: ExecutionContext): Future[Any] = {
Future.successful(
if (empty)
StaticBlockOutput()
else
StaticBlockOutput(request.content)
)
}
}
implicit class BlockProcessorOps[T](request: T)(implicit ev: BlockProcessor[T]) {
def processBlock(project: String, userEmail: String, empty: Boolean): Future[Any] = ev.processBlock(request, project, userEmail, empty)
}
Then I have no problems to run something like:
StaticBlockInput("test string").processBlock("myProject","[email protected]",false)
But what if my input was created by reflection from some other part of code and actual class type is erased and all I have is an instance of generic type and manifest:
val manifest: Manifest[I <: BlockInputRequest] = ... // type is saved
val block: BlockInputRequest = ... // created using reflection
block.processBlock("myProject","[email protected]",false)
Is there a way I can resolve BlockProcessor
? Or maybe I can use reflection again in some way?