Skip to content

Instantly share code, notes, and snippets.

@sergeykolbasov
Last active March 21, 2016 20:43
Show Gist options
  • Save sergeykolbasov/eeb80eda1c26b623d244 to your computer and use it in GitHub Desktop.
Save sergeykolbasov/eeb80eda1c26b623d244 to your computer and use it in GitHub Desktop.
FromParams with love to Option
package io.finch.internal
import scala.reflect.ClassTag
import io.finch._
import shapeless._
import shapeless.labelled._
/**
* A type class empowering a generic derivation of [[Endpoint]]s from query string params.
*/
trait FromParams[L <: HList] {
def endpoint: Endpoint[L]
}
object Extractor extends Poly1 {
implicit def optionalExtractor[V](implicit
dh: Decode[V],
ct: ClassTag[V]
): Case.Aux[String, Endpoint[Option[V]]] = at[String] { key =>
paramOption(key).as(dh, ct)
}
implicit def seqExtractor[V](implicit
dh: Decode[V],
ct: ClassTag[V]
): Case.Aux[String, Endpoint[Seq[V]]] = at[String] { key =>
params(key).as(dh, ct)
}
implicit def extractor[V](implicit
dh: Decode[V],
ct: ClassTag[V]
): Case.Aux[String, Endpoint[V]] = at[String] { key =>
param(key).as(dh, ct)
}
}
object FromParams extends Cases{
implicit val hnilFromParams: FromParams[HNil] = new FromParams[HNil] {
def endpoint: Endpoint[HNil] = Endpoint.Empty
}
implicit def hconsFromParams[HK <: Symbol, HV, T <: HList](implicit
key: Witness.Aux[HK],
fpt: FromParams[T],
hс: Case1.Aux[Extractor.type, String, Endpoint[HV]]
): FromParams[FieldType[HK, HV] :: T] = new FromParams[FieldType[HK, HV] :: T] {
def endpoint: Endpoint[FieldType[HK, HV] :: T] =
hс(key.value.name).map(field[HK](_)) :: fpt.endpoint
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment