+htc apply smaller extensions and simplifications

This commit is contained in:
Mathias 2014-11-11 16:21:36 +01:00
parent b285fa0c55
commit 5b126b6d8b
6 changed files with 50 additions and 17 deletions

View file

@ -15,13 +15,23 @@ final case class ContentTypeRange(mediaRange: MediaRange, charsetRange: HttpChar
case HttpCharsetRange.`*` r ~~ mediaRange
case x r ~~ mediaRange ~~ ContentType.`; charset=` ~~ x
}
/**
* Returns a [[ContentType]] instance which fits this range.
*/
def specimen: ContentType = ContentType(mediaRange.specimen, charsetRange.specimen)
}
object ContentTypeRange {
val `*` = ContentTypeRange(MediaRanges.`*/*`)
implicit def apply(mediaType: MediaType): ContentTypeRange = apply(MediaRange(mediaType), HttpCharsetRange.`*`)
implicit def apply(mediaType: MediaType): ContentTypeRange = apply(mediaType, HttpCharsetRange.`*`)
implicit def apply(mediaRange: MediaRange): ContentTypeRange = apply(mediaRange, HttpCharsetRange.`*`)
implicit def apply(contentType: ContentType): ContentTypeRange =
contentType.definedCharset match {
case Some(charset) apply(contentType.mediaType, charset)
case None ContentTypeRange(contentType.mediaType)
}
}
final case class ContentType(mediaType: MediaType, definedCharset: Option[HttpCharset]) extends japi.ContentType with ValueRenderable {

View file

@ -5,14 +5,16 @@
package akka.http.model
/**
* Model for `application/x-www-form-urlencoded` form data.
* Simple model for `application/x-www-form-urlencoded` form data.
*/
final case class FormData(fields: Uri.Query) {
type FieldType = (String, String)
}
final case class FormData(fields: Uri.Query)
object FormData {
val Empty = FormData(Uri.Query.Empty)
def apply(fields: Map[String, String]): FormData =
if (fields.isEmpty) Empty else FormData(Uri.Query(fields))
def apply(fields: (String, String)*): FormData =
if (fields.isEmpty) Empty else FormData(Uri.Query(fields: _*))
}

View file

@ -19,6 +19,11 @@ sealed abstract class HttpCharsetRange extends japi.HttpCharsetRange with ValueR
def qValue: Float
def matches(charset: HttpCharset): Boolean
/**
* Returns a [[HttpCharset]] instance which fits this range.
*/
def specimen: HttpCharset
/** Java API */
def matches(charset: japi.HttpCharset): Boolean = {
import japi.JavaMapping.Implicits._
@ -32,7 +37,7 @@ object HttpCharsetRange {
final def render[R <: Rendering](r: R): r.type = if (qValue < 1.0f) r ~~ "*;q=" ~~ qValue else r ~~ '*'
def matches(charset: HttpCharset) = true
def matchesAll: Boolean = true
def specimen = HttpCharsets.`UTF-8`
def withQValue(qValue: Float) =
if (qValue == 1.0f) `*` else if (qValue != this.qValue) `*`(qValue.toFloat) else this
}
@ -42,7 +47,7 @@ object HttpCharsetRange {
require(0.0f <= qValue && qValue <= 1.0f, "qValue must be >= 0 and <= 1.0")
def matches(charset: HttpCharset) = this.charset.value.equalsIgnoreCase(charset.value)
def matchesAll: Boolean = false
def specimen = charset
def withQValue(qValue: Float) = One(charset, qValue)
def render[R <: Rendering](r: R): r.type = if (qValue < 1.0f) r ~~ charset ~~ ";q=" ~~ qValue else r ~~ charset
}

View file

@ -250,7 +250,8 @@ final case class HttpRequest(method: HttpMethod = HttpMethods.GET,
override def withMethod(method: akka.http.model.japi.HttpMethod): HttpRequest = copy(method = method.asInstanceOf[HttpMethod])
override def withProtocol(protocol: akka.http.model.japi.HttpProtocol): HttpRequest = copy(protocol = protocol.asInstanceOf[HttpProtocol])
override def withUri(path: String): HttpRequest = copy(uri = Uri(path))
override def withUri(path: String): HttpRequest = withUri(Uri(path))
def withUri(uri: Uri): HttpRequest = copy(uri = uri)
/** Java API */
override def getUri: japi.Uri = japi.Accessors.Uri(uri)

View file

@ -34,6 +34,11 @@ sealed abstract class MediaRange extends japi.MediaRange with Renderable with Wi
*/
def withCharset(charsetRange: HttpCharsetRange): ContentTypeRange = ContentTypeRange(this, charsetRange)
/**
* Returns a [[MediaType]] instance which fits this range.
*/
def specimen: MediaType
/** Java API */
def getParams: util.Map[String, String] = {
import collection.JavaConverters._
@ -72,6 +77,7 @@ object MediaRange {
override def isMultipart = mainType == "multipart"
override def isText = mainType == "text"
override def isVideo = mainType == "video"
def specimen = MediaType.custom(mainType, "custom")
}
def custom(mainType: String, params: Map[String, String] = Map.empty, qValue: Float = 1.0f): MediaRange = {
@ -95,6 +101,7 @@ object MediaRange {
def withParams(params: Map[String, String]) = copy(mediaType = mediaType.withParams(params))
def withQValue(qValue: Float) = copy(qValue = qValue)
def render[R <: Rendering](r: R): r.type = if (qValue < 1.0f) r ~~ mediaType ~~ ";q=" ~~ qValue else r ~~ mediaType
def specimen = mediaType
}
implicit def apply(mediaType: MediaType): MediaRange = apply(mediaType, 1.0f)
@ -114,34 +121,42 @@ object MediaRanges extends ObjectRegistry[String, MediaRange] {
val `*/*` = new PredefinedMediaRange("*/*") {
def matches(mediaType: MediaType) = true
def specimen = MediaTypes.`text/plain`
}
val `application/*` = new PredefinedMediaRange("application/*") {
def matches(mediaType: MediaType) = mediaType.isApplication
override def isApplication: Boolean = true
override def isApplication = true
def specimen = MediaTypes.`application/json`
}
val `audio/*` = new PredefinedMediaRange("audio/*") {
def matches(mediaType: MediaType) = mediaType.isAudio
override def isAudio: Boolean = true
override def isAudio = true
def specimen = MediaTypes.`audio/ogg`
}
val `image/*` = new PredefinedMediaRange("image/*") {
def matches(mediaType: MediaType) = mediaType.isImage
override def isImage: Boolean = true
override def isImage = true
def specimen = MediaTypes.`image/png`
}
val `message/*` = new PredefinedMediaRange("message/*") {
def matches(mediaType: MediaType) = mediaType.isMessage
override def isMessage: Boolean = true
override def isMessage = true
def specimen = MediaTypes.`message/rfc822`
}
val `multipart/*` = new PredefinedMediaRange("multipart/*") {
def matches(mediaType: MediaType) = mediaType.isMultipart
override def isMultipart: Boolean = true
override def isMultipart = true
def specimen = MediaTypes.`multipart/form-data`
}
val `text/*` = new PredefinedMediaRange("text/*") {
def matches(mediaType: MediaType) = mediaType.isText
override def isText: Boolean = true
override def isText = true
def specimen = MediaTypes.`text/plain`
}
val `video/*` = new PredefinedMediaRange("video/*") {
def matches(mediaType: MediaType) = mediaType.isVideo
override def isVideo: Boolean = true
override def isVideo = true
def specimen = MediaTypes.`video/mp4`
}
}

View file

@ -198,7 +198,7 @@ object Multipart {
def additionalDispositionParams = _additionalDispositionParams
def additionalHeaders = _additionalHeaders
def entity = _entity
override def toString = s"FormData.BodyPart(${_name}, ${_entity}, ${_additionalDispositionParams}, ${_additionalHeaders})"
override def toString = s"FormData.BodyPart($name, $entity, $additionalDispositionParams, $additionalHeaders)"
}
def unapply(value: BodyPart): Option[(String, BodyPartEntity, Map[String, String], immutable.Seq[HttpHeader])] =
@ -266,7 +266,7 @@ object Multipart {
def entity = _entity
def rangeUnit = _rangeUnit
def additionalHeaders = _additionalHeaders
override def toString = s"ByteRanges.BodyPart(${_contentRange}, ${_entity}, ${_rangeUnit}, ${_additionalHeaders})"
override def toString = s"ByteRanges.BodyPart($contentRange, $entity, $rangeUnit, $additionalHeaders)"
}
def unapply(value: BodyPart): Option[(ContentRange, BodyPartEntity, RangeUnit, immutable.Seq[HttpHeader])] =