private[this] def extractMatchingParameterValues()

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
    }
  }