All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scalaz.http.request.Uri.scala Maven / Gradle / Ivy

The newest version!
package scalaz
package http
package request

import Util.Nel._
import Scalaz._

/**
 * HTTP request URI.
 * RFC 2616 Section 5.1.2 Request-URI.
 *
 * @author Tony Morris
 */
sealed trait Uri {
  /**
   * The path of this request URI.
   */
  val path: NonEmptyList[Char]

  /**
   * The query string of this request URI.
   */
  val queryString: Option[List[Char]]

  import Uri.uri

  /**
   * Returns a request URI with the given path and this query string.
   */
  def apply(p: NonEmptyList[Char]) = uri(p, queryString)

  /**
   * Returns a request URI with the given potential query string and this path.
   */
  def apply(q: Option[List[Char]]) = uri(path, q)

  /**
   * Returns a request URI after applying the given transformation to the path.
   */
  def +++(f: NonEmptyList[Char] => NonEmptyList[Char]) = uri(f(this.path), queryString)

  /**
   * Returns a request URI after applying the given transformation to the query string.
   */
  def ++++(f: Option[List[Char]] => Option[List[Char]]) = uri(path, f(this.queryString))

  /**
   * Returns the path extension - characters after the last dot (.) in the path.
   */
  lazy val pathExtension = path.dropWhile(_ != '.').reverse.takeWhile(_ != '.').reverse.mkString
  
  lazy val parts : List[String] = {
    path.list.reverse.foldLeft(List[List[Char]](Nil))((rs, ch) => {
      if (ch == '/') { Nil :: rs } else { (ch :: rs.head)  :: rs.tail }
    }).filter(!_.isEmpty).map(_.mkString)
  }

  import Util.{asHashMap, mapHeads}

  /**
   * Returns the query string split into values by '='.
   */
  lazy val parameters = queryString ∘ (Util.parameters(_))

  /**
   * Returns the query string split into values by '=' backed with a hash map.
   */
  lazy val parametersMap = parameters ∘ (asHashMap[List, NonEmptyList](_))

  /**
   * Returns the query string split into values by '=' (removing duplicate values for a given key) backed
   * with a hash map.
   */
  lazy val parametersMapHeads = parametersMap ∘ (mapHeads(_))
}

trait Uris {
  /**
   * Takes the given string and splits it into a URI and query string by '?' character.
   */
  implicit def ListUri(cs: List[Char]): Option[Uri] = cs match {
    case Nil => None
    case x :: _ if x == '?' => None
    case h :: t => {
      val z = t.span(_ != '?')
      Some(Uri.uri(nel(h, z._1), z._2 match {
        case Nil => None
        case _ :: Nil => None
        case _ :: k => Some(k)
      }))
    }
  }
}

/*
 * HTTP request URI.
 * RFC 2616 Section 5.1.2 Request-URI.
 */
object Uri extends Uris {
  /**
   * An extractor that always matches with the URI path and query string.
   */
  def unapply(uri: Uri): Option[(NonEmptyList[Char], Option[List[Char]])] =
    Some(uri.path, uri.queryString)

  /**
   * Constructs a URI with the given path and query string.
   */
  def uri(p: NonEmptyList[Char], s: Option[List[Char]]) = new Uri {
    val path = p
    val queryString = s
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy