Merge pull request #17552 from spray/w/fix-implicits

=htp add explicit result types to formField/parameter implicits
This commit is contained in:
drewhk 2015-05-28 12:51:13 +02:00
commit e2eab532ab
4 changed files with 31 additions and 36 deletions

View file

@ -9,9 +9,6 @@ import akka.http.scaladsl.server.Route
import akka.http.scaladsl.model._
class FormFieldDirectivesExamplesSpec extends RoutingSpec {
// FIXME: investigate why it doesn't work without this import
import akka.http.scaladsl.server.directives.FormFieldDirectives.FieldMagnet
"formFields" in {
val route =
formFields('color, 'age.as[Int]) { (color, age) =>

View file

@ -9,9 +9,6 @@ import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Route
class ParameterDirectivesExamplesSpec extends RoutingSpec {
// FIXME: investigate why it doesn't work without this import
import akka.http.scaladsl.server.directives.ParameterDirectives.ParamMagnet
"example-1" in {
val route =
parameter('color) { color =>

View file

@ -35,20 +35,20 @@ object FormFieldDirectives extends FormFieldDirectives {
def apply(): Out
}
object FieldMagnet {
implicit def apply[T](value: T)(implicit fdef: FieldDef[T]) =
implicit def apply[T](value: T)(implicit fdef: FieldDef[T]): FieldMagnet { type Out = fdef.Out } =
new FieldMagnet {
type Out = fdef.Out
def apply() = fdef(value)
}
}
type FieldDefAux[A, B] = FieldDef[A] { type Out = B }
sealed trait FieldDef[T] {
type Out
def apply(value: T): Out
}
object FieldDef {
def fieldDef[A, B](f: A B) =
def fieldDef[A, B](f: A B): FieldDefAux[A, B] =
new FieldDef[A] {
type Out = B
def apply(value: A) = f(value)
@ -63,7 +63,7 @@ object FormFieldDirectives extends FormFieldDirectives {
//////////////////// "regular" formField extraction ////////////////////
private def extractField[A, B](f: A Directive1[B]) = fieldDef(f)
private def extractField[A, B](f: A Directive1[B]): FieldDefAux[A, Directive1[B]] = fieldDef(f)
private def fieldOfForm[T](fieldName: String, fu: Unmarshaller[Option[StrictForm.Field], T])(implicit sfu: SFU): RequestContext Future[T] = { ctx
import ctx.executionContext
sfu(ctx.request.entity).fast.flatMap(form fu(form field fieldName))
@ -78,21 +78,21 @@ object FormFieldDirectives extends FormFieldDirectives {
}
}
}
implicit def forString(implicit sfu: SFU, fu: FSFFU[String]) =
implicit def forString(implicit sfu: SFU, fu: FSFFU[String]): FieldDefAux[String, Directive1[String]] =
extractField[String, String] { fieldName filter(fieldName, fu) }
implicit def forSymbol(implicit sfu: SFU, fu: FSFFU[String]) =
implicit def forSymbol(implicit sfu: SFU, fu: FSFFU[String]): FieldDefAux[Symbol, Directive1[String]] =
extractField[Symbol, String] { symbol filter(symbol.name, fu) }
implicit def forNR[T](implicit sfu: SFU, fu: FSFFU[T]) =
implicit def forNR[T](implicit sfu: SFU, fu: FSFFU[T]): FieldDefAux[NameReceptacle[T], Directive1[T]] =
extractField[NameReceptacle[T], T] { nr filter(nr.name, fu) }
implicit def forNUR[T](implicit sfu: SFU) =
implicit def forNUR[T](implicit sfu: SFU): FieldDefAux[NameUnmarshallerReceptacle[T], Directive1[T]] =
extractField[NameUnmarshallerReceptacle[T], T] { nr filter(nr.name, StrictForm.Field.unmarshallerFromFSU(nr.um)) }
implicit def forNOR[T](implicit sfu: SFU, fu: FSFFOU[T]) =
implicit def forNOR[T](implicit sfu: SFU, fu: FSFFOU[T]): FieldDefAux[NameOptionReceptacle[T], Directive1[Option[T]]] =
extractField[NameOptionReceptacle[T], Option[T]] { nr filter[Option[T]](nr.name, fu) }
implicit def forNDR[T](implicit sfu: SFU, fu: FSFFOU[T]) =
implicit def forNDR[T](implicit sfu: SFU, fu: FSFFOU[T]): FieldDefAux[NameDefaultReceptacle[T], Directive1[T]] =
extractField[NameDefaultReceptacle[T], T] { nr filter(nr.name, fu withDefaultValue nr.default) }
implicit def forNOUR[T](implicit sfu: SFU) =
implicit def forNOUR[T](implicit sfu: SFU): FieldDefAux[NameOptionUnmarshallerReceptacle[T], Directive1[Option[T]]] =
extractField[NameOptionUnmarshallerReceptacle[T], Option[T]] { nr filter[Option[T]](nr.name, StrictForm.Field.unmarshallerFromFSU(nr.um): FSFFOU[T]) }
implicit def forNDUR[T](implicit sfu: SFU) =
implicit def forNDUR[T](implicit sfu: SFU): FieldDefAux[NameDefaultUnmarshallerReceptacle[T], Directive1[T]] =
extractField[NameDefaultUnmarshallerReceptacle[T], T] { nr filter(nr.name, (StrictForm.Field.unmarshallerFromFSU(nr.um): FSFFOU[T]) withDefaultValue nr.default) }
//////////////////// required formField support ////////////////////
@ -105,9 +105,9 @@ object FormFieldDirectives extends FormFieldDirectives {
case _ reject
}
}
implicit def forRVR[T](implicit sfu: SFU, fu: FSFFU[T]) =
implicit def forRVR[T](implicit sfu: SFU, fu: FSFFU[T]): FieldDefAux[RequiredValueReceptacle[T], Directive0] =
fieldDef[RequiredValueReceptacle[T], Directive0] { rvr requiredFilter(rvr.name, fu, rvr.requiredValue) }
implicit def forRVDR[T](implicit sfu: SFU) =
implicit def forRVDR[T](implicit sfu: SFU): FieldDefAux[RequiredValueUnmarshallerReceptacle[T], Directive0] =
fieldDef[RequiredValueUnmarshallerReceptacle[T], Directive0] { rvr requiredFilter(rvr.name, StrictForm.Field.unmarshallerFromFSU(rvr.um), rvr.requiredValue) }
//////////////////// tuple support ////////////////////
@ -115,11 +115,11 @@ object FormFieldDirectives extends FormFieldDirectives {
import akka.http.scaladsl.server.util.TupleOps._
import akka.http.scaladsl.server.util.BinaryPolyFunc
implicit def forTuple[T](implicit fold: FoldLeft[Directive0, T, ConvertParamDefAndConcatenate.type]) =
implicit def forTuple[T](implicit fold: FoldLeft[Directive0, T, ConvertParamDefAndConcatenate.type]): FieldDefAux[T, fold.Out] =
fieldDef[T, fold.Out](fold(pass, _))
object ConvertParamDefAndConcatenate extends BinaryPolyFunc {
implicit def from[P, TA, TB](implicit fdef: FieldDef[P] { type Out = Directive[TB] }, ev: Join[TA, TB]) =
implicit def from[P, TA, TB](implicit fdef: FieldDefAux[P, Directive[TB]], ev: Join[TA, TB]) =
at[Directive[TA], P] { (a, t) a & fdef(t) }
}
}

View file

@ -59,19 +59,20 @@ object ParameterDirectives extends ParameterDirectives {
def apply(): Out
}
object ParamMagnet {
implicit def apply[T](value: T)(implicit pdef: ParamDef[T]) =
implicit def apply[T](value: T)(implicit pdef: ParamDef[T]): ParamMagnet { type Out = pdef.Out } =
new ParamMagnet {
type Out = pdef.Out
def apply() = pdef(value)
}
}
type ParamDefAux[T, U] = ParamDef[T] { type Out = U }
sealed trait ParamDef[T] {
type Out
def apply(value: T): Out
}
object ParamDef {
def paramDef[A, B](f: A B) =
def paramDef[A, B](f: A B): ParamDefAux[A, B] =
new ParamDef[A] {
type Out = B
def apply(value: A) = f(value)
@ -85,7 +86,7 @@ object ParameterDirectives extends ParameterDirectives {
//////////////////// "regular" parameter extraction //////////////////////
private def extractParameter[A, B](f: A Directive1[B]) = paramDef(f)
private def extractParameter[A, B](f: A Directive1[B]): ParamDefAux[A, Directive1[B]] = paramDef(f)
private def filter[T](paramName: String, fsou: FSOU[T]): Directive1[T] =
extractRequestContext flatMap { ctx
import ctx.executionContext
@ -95,21 +96,21 @@ object ParameterDirectives extends ParameterDirectives {
case Failure(x) reject(MalformedQueryParamRejection(paramName, x.getMessage.nullAsEmpty, Option(x.getCause)))
}
}
implicit def forString(implicit fsu: FSU[String]) =
implicit def forString(implicit fsu: FSU[String]): ParamDefAux[String, Directive1[String]] =
extractParameter[String, String] { string filter(string, fsu) }
implicit def forSymbol(implicit fsu: FSU[String]) =
implicit def forSymbol(implicit fsu: FSU[String]): ParamDefAux[Symbol, Directive1[String]] =
extractParameter[Symbol, String] { symbol filter(symbol.name, fsu) }
implicit def forNR[T](implicit fsu: FSU[T]) =
implicit def forNR[T](implicit fsu: FSU[T]): ParamDefAux[NameReceptacle[T], Directive1[T]] =
extractParameter[NameReceptacle[T], T] { nr filter(nr.name, fsu) }
implicit def forNUR[T] =
implicit def forNUR[T]: ParamDefAux[NameUnmarshallerReceptacle[T], Directive1[T]] =
extractParameter[NameUnmarshallerReceptacle[T], T] { nr filter(nr.name, nr.um) }
implicit def forNOR[T](implicit fsou: FSOU[T]) =
implicit def forNOR[T](implicit fsou: FSOU[T]): ParamDefAux[NameOptionReceptacle[T], Directive1[Option[T]]] =
extractParameter[NameOptionReceptacle[T], Option[T]] { nr filter[Option[T]](nr.name, fsou) }
implicit def forNDR[T](implicit fsou: FSOU[T]) =
implicit def forNDR[T](implicit fsou: FSOU[T]): ParamDefAux[NameDefaultReceptacle[T], Directive1[T]] =
extractParameter[NameDefaultReceptacle[T], T] { nr filter[T](nr.name, fsou withDefaultValue nr.default) }
implicit def forNOUR[T] =
implicit def forNOUR[T]: ParamDefAux[NameOptionUnmarshallerReceptacle[T], Directive1[Option[T]]] =
extractParameter[NameOptionUnmarshallerReceptacle[T], Option[T]] { nr filter(nr.name, nr.um: FSOU[T]) }
implicit def forNDUR[T] =
implicit def forNDUR[T]: ParamDefAux[NameDefaultUnmarshallerReceptacle[T], Directive1[T]] =
extractParameter[NameDefaultUnmarshallerReceptacle[T], T] { nr filter[T](nr.name, (nr.um: FSOU[T]) withDefaultValue nr.default) }
//////////////////// required parameter support ////////////////////
@ -122,9 +123,9 @@ object ParameterDirectives extends ParameterDirectives {
case _ reject
}
}
implicit def forRVR[T](implicit fsu: FSU[T]) =
implicit def forRVR[T](implicit fsu: FSU[T]): ParamDefAux[RequiredValueReceptacle[T], Directive0] =
paramDef[RequiredValueReceptacle[T], Directive0] { rvr requiredFilter(rvr.name, fsu, rvr.requiredValue) }
implicit def forRVDR[T] =
implicit def forRVDR[T]: ParamDefAux[RequiredValueUnmarshallerReceptacle[T], Directive0] =
paramDef[RequiredValueUnmarshallerReceptacle[T], Directive0] { rvr requiredFilter(rvr.name, rvr.um, rvr.requiredValue) }
//////////////////// tuple support ////////////////////
@ -132,7 +133,7 @@ object ParameterDirectives extends ParameterDirectives {
import akka.http.scaladsl.server.util.TupleOps._
import akka.http.scaladsl.server.util.BinaryPolyFunc
implicit def forTuple[T](implicit fold: FoldLeft[Directive0, T, ConvertParamDefAndConcatenate.type]) =
implicit def forTuple[T](implicit fold: FoldLeft[Directive0, T, ConvertParamDefAndConcatenate.type]): ParamDefAux[T, fold.Out] =
paramDef[T, fold.Out](fold(BasicDirectives.pass, _))
object ConvertParamDefAndConcatenate extends BinaryPolyFunc {