/R/route.r

http://github.com/hadley/sinartra · R · 51 lines · 27 code · 7 blank · 17 comment · 3 complexity · 9d1d4b4e55545a38793b8a17e393b8c2 MD5 · raw file

  1. #' Parse route (with parameters) into regular expression.
  2. #'
  3. #' @param route route url.
  4. #' @return
  5. #' \item{match}{regular expression to match route}
  6. #' \item{params}{parameter names}
  7. route_re <- function(route) {
  8. # Escape special characters that can occur in both urls and regexps
  9. route <- stringr::str_replace_all(route, "([.])", "\\\\\\1")
  10. # Extract parameters
  11. params <- stringr::str_extract_all(route, ":[a-zA-Z0-9_.]+|[*]")[[1]]
  12. keys <- stringr::str_replace_all(params, ":", "")
  13. keys[keys == "*"] <- "splat"
  14. match <- stringr::str_c("^", route, "$")
  15. match <- stringr::str_replace_all(match, ":[a-zA-Z0-9_.]+", "([^/?&#]+)")
  16. match <- stringr::str_replace_all(match, "[*]", "(.*?)")
  17. list(
  18. match = stringr::str_c(match, collapse = "/"),
  19. params = keys
  20. )
  21. }
  22. #' Generate functions to match specified route.
  23. #'
  24. #' @param route route url
  25. #' @return
  26. #' \item{match}{function returning \code{TRUE} if argument matches route,
  27. #' \code{FALSE} otherwise}
  28. #' \item{params}{function that parses path and returns named list of
  29. #' parameters}
  30. route_matcher <- function(route) {
  31. re <- route_re(route)
  32. list(
  33. match = function(path) stringr::str_detect(path, re$match),
  34. params = function(path) {
  35. matches <- stringr::str_match(path, re$match)[1, -1]
  36. if (length(re$params) > 0) {
  37. # c is simplest way convert from array to vector
  38. c(tapply(matches, re$params, "c", simplify = FALSE))
  39. } else {
  40. list()
  41. }
  42. }
  43. )
  44. }