in finagle-http/src/main/scala/com/twitter/finagle/http/exp/routing/PathMatcher.scala [357:414]
private[this] def extractMatchingParameterValues(
iter: Iterator[Segment],
str: String,
idx: Int = 0,
parameters: Map[String, ParameterValue] = Map.empty
): Map[String, ParameterValue] = {
requireNonNegativeIdx(idx)
if (idx < str.length && iter.hasNext) {
val segment = iter.next()
segment match {
case Slash =>
val found = indexAfterMatchingSlash(str, idx)
if (found >= 0) extractMatchingParameterValues(iter, str, found, parameters)
else Map.empty
case Constant(path) =>
val found = indexAfterRegionMatch(str, idx, path)
if (found >= 0) extractMatchingParameterValues(iter, str, found, parameters)
else Map.empty
case param: Parameterized if iter.hasNext =>
// if we have remaining segments, we need to find the next segment in order to extract
// the dynamic value between segments
val nextSegment = iter.next()
// note: we use match instead of flatMap to keep extractSegments in tail position
parameterized(str, idx, param, nextSegment) match {
case ParsedValue(nextEnd, parameterValue) =>
extractMatchingParameterValues(
iter,
str,
nextEnd,
parameters + (param.param.name -> parameterValue))
case _ =>
Map.empty
}
case param: Parameterized =>
// otherwise there is no next segment and we have a trailing parameter to extract
parameterizedEnd(str, idx, param) match {
case Some(parameterValue) =>
val updatedMap = parameters + (param.param.name -> parameterValue)
updatedMap
case _ =>
Map.empty
}
case _ =>
Map.empty
}
} else if (idx == str.length) {
parameters
} else {
Map.empty
}
}