Skip to content

Instantly share code, notes, and snippets.

@tobnee
Created June 30, 2016 09:07
Show Gist options
  • Save tobnee/02c2d9abc6046fdab353875e27ebee16 to your computer and use it in GitHub Desktop.
Save tobnee/02c2d9abc6046fdab353875e27ebee16 to your computer and use it in GitHub Desktop.
query builder helper for play
object UriBuilder {
def base(base: String) = new UriBuilder(base, Vector.empty, Vector.empty)
}
case class UriBuilder(
base: String, path: Vector[String], query: Vector[(String, String)]) {
def path(segments: String*): UriBuilder =
new UriBuilder(base, segments.toVector, Vector.empty)
def query(values: (String, String)*): UriBuilder =
copy(query = query ++ values.toVector)
def queryOpt(values: (String, Option[String])*): UriBuilder =
copy(query = query ++ values.toVector.collect{ case (k, Some(v)) => k -> v })
def build(values: (String, String)*): String = {
val qValues = values.toVector ++ query
val lengthEstimate =
base.length + path.foldLeft(0)((a, v) => a + v.length + 1) +
qValues.foldLeft(0)((a, kv) => kv._1.length + kv._2.length + 2)
val sb = new StringBuilder(lengthEstimate)
sb.append(base)
path.addString(sb, "/", "/", "")
def toQueryParam(start: Char, p: (String, String)) =
sb.append(start).append(p._1).append('=').append(p._2)
qValues match {
case head +: tail =>
toQueryParam('?', head)
tail.foreach(kv => toQueryParam('&', kv))
case _ =>
}
sb.toString()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment