One way to understand it is to rewrite this expression the way that it gets rewritten by the Scala compiler.
unfiltered.netty.cycle.Planify
expects a PartialFunction[HttpRequest[ReceivedMessage], ResponseFunction[NHttpResponse]]
, that is, a function that may or may not match the argument. If there's no match in either of the case
statements, the request gets ignored. If there is a match -- which also has to pass all of the extractors -- the response will be returned.
Each case
statement gets an instance of HttpRequest[ReceivedMessage]
. Then, it applies it with left associativity through a series of unapply
methods for each of the matchers:
// The request passed to us is HttpRequest[ReceivedMessage]
// GET.unapply only returns Some if the method is GET
GET.unapply(request) flatMap { getRequest =>
// this separates the path from the query
Path.unapply(getRequest) flatMap { path =>
// splits the path by "/"
Seg.unapply(path) flatMap { listOfParams =>
// Calls to unapply don't end here - now we build an
// instance of :: class, which
// since a :: b is the same as ::(a, b)
::.unapply(::(listOfParams.head, listOfParams.tail)) flatMap { case (p, restOfP) =>
::.unapply(::(restOfP.head, Nil)) map { case (q, _) =>
ResponseString("Hello World! " + p + " " + q)
}
}
}
}
}
Hopefully, this gives you an idea of how the matching works behind the scenes. I'm not entirely sure if I got the ::
bit right - comments are welcome.