Skip to content
This repository has been archived by the owner on Apr 24, 2024. It is now read-only.

Commit

Permalink
Merge pull request #382 from jrudolph/wip/274
Browse files Browse the repository at this point in the history
! routing: PathMatcher.(flat)map => h(flat)map, introduce map/flatMap, fixes #274
  • Loading branch information
sirthias committed Jul 18, 2013
2 parents 1943bca + 8c91851 commit 7222a6f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 12 deletions.
Expand Up @@ -273,12 +273,28 @@ class PathDirectivesSpec extends RoutingSpec {
}

"PathMatchers" should {
"support the map modifier" in {
"support the hmap modifier" in {
import shapeless._
Get("/yes-no") ~> {
path(Rest.map { case s :: HNil s.split('-').toList :: HNil }) { echoComplete }
path(Rest.hmap { case s :: HNil s.split('-').toList :: HNil }) { echoComplete }
} ~> check { entityAs[String] === "List(yes, no)" }
}
"support the map modifier" in {
Get("/yes-no") ~> {
path(Rest.map(_.split('-').toList)) { echoComplete }
} ~> check { entityAs[String] === "List(yes, no)" }
}
"support the hflatMap modifier" in {
import shapeless._
val route = path(Rest.hflatMap { case s :: HNil Some(s).filter("yes" ==).map(_ :: HNil) }) { echoComplete }
Get("/yes") ~> route ~> check { entityAs[String] === "yes" }
Get("/blub") ~> route ~> check { handled must beFalse }
}
"support the flatMap modifier" in {
val route = path(Rest.flatMap(s Some(s).filter("yes" ==))) { echoComplete }
Get("/yes") ~> route ~> check { entityAs[String] === "yes" }
Get("/blub") ~> route ~> check { handled must beFalse }
}
"support the `|` operator" in {
val route = path("ab" / ("cd" | "ef") / "gh") { completeOk }
"example 1" in {
Expand Down
24 changes: 14 additions & 10 deletions spray-routing/src/main/scala/spray/routing/PathMatcher.scala
Expand Up @@ -49,9 +49,9 @@ trait PathMatcher[L <: HList] extends (Path ⇒ PathMatcher.Matching[L]) { self
def transform[R <: HList](f: Matching[L] Matching[R]): PathMatcher[R] =
new PathMatcher[R] { def apply(path: Path) = f(self(path)) }

def map[R <: HList](f: L R): PathMatcher[R] = transform(_.map(f))
def hmap[R <: HList](f: L R): PathMatcher[R] = transform(_.map(f))

def flatMap[R <: HList](f: L Option[R]): PathMatcher[R] = transform(_.flatMap(f))
def hflatMap[R <: HList](f: L Option[R]): PathMatcher[R] = transform(_.flatMap(f))
}

object PathMatcher extends ImplicitPathMatcherConstruction {
Expand Down Expand Up @@ -97,6 +97,12 @@ object PathMatcher extends ImplicitPathMatcherConstruction {
}

def apply[L <: HList](magnet: PathMatcher[L]): PathMatcher[L] = magnet

implicit class PathMatcher1Ops[T](matcher: PathMatcher1[T]) {
def map[R](f: T R): PathMatcher1[R] = matcher.hmap { case e :: HNil f(e) :: HNil }
def flatMap[R](f: T Option[R]): PathMatcher1[R] =
matcher.hflatMap { case e :: HNil f(e).map(_ :: HNil) }
}
}

trait ImplicitPathMatcherConstruction {
Expand Down Expand Up @@ -303,20 +309,18 @@ trait PathMatchers {
* optionally signed form of a double value, i.e. without exponent.
*/
val DoubleNumber = PathMatcher("""[+-]?\d*\.?\d*""".r)
.flatMap {
case string :: HNil
try Some(java.lang.Double.parseDouble(string) :: HNil)
catch { case _: NumberFormatException None }
.flatMap { string
try Some(java.lang.Double.parseDouble(string))
catch { case _: NumberFormatException None }
}

/**
* A PathMatcher that matches and extracts a java.util.UUID instance.
*/
val JavaUUID = PathMatcher("""[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}""".r)
.flatMap {
case string :: HNil
try Some(UUID.fromString(string) :: HNil)
catch { case _: IllegalArgumentException None }
.flatMap { string
try Some(UUID.fromString(string))
catch { case _: IllegalArgumentException None }
}

/**
Expand Down

0 comments on commit 7222a6f

Please sign in to comment.