Skip to content

Commit

Permalink
Merge pull request http4s#895 from http4s/topic/fix-tuts-and-syntax
Browse files Browse the repository at this point in the history
Fix the tuts broken by http4s#810, reform syntax
  • Loading branch information
rossabaker authored Jan 28, 2017
2 parents b618c2f + 57d1f68 commit 57f1727
Show file tree
Hide file tree
Showing 51 changed files with 201 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.http4s.blaze.channel.nio2.ClientChannelFactory
import org.http4s.util.task
import org.http4s.blaze.pipeline.{Command, LeafBuilder}
import org.http4s.blaze.pipeline.stages.SSLStage
import org.http4s.util.CaseInsensitiveString._
import org.http4s.syntax.string._

import scala.concurrent.ExecutionContext
import scala.concurrent.Future
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import java.nio.ByteBuffer

import org.http4s.blaze.SeqTestHead
import org.http4s.blaze.pipeline.LeafBuilder
import org.http4s.util.CaseInsensitiveString._
import bits.DefaultUserAgent
import org.specs2.mutable.Specification
import scodec.bits.ByteVector
Expand All @@ -18,7 +17,7 @@ import scalaz.\/-
import scalaz.concurrent.{Strategy, Task}

// TODO: this needs more tests
class Http1ClientStageSpec extends Specification {
class Http1ClientStageSpec extends Http4sSpec {

val ec = org.http4s.blaze.util.Execution.trampoline
val es = Strategy.DefaultExecutorService
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import org.http4s.blaze.util.BufferTools.emptyBuffer
import org.http4s.blaze.http.http_parser.BaseExceptions.{BadRequest, ParserException}

import org.http4s.util.StringWriter
import org.http4s.util.CaseInsensitiveString._
import org.http4s.syntax.string._
import org.http4s.headers.{Connection, `Content-Length`, `Transfer-Encoding`}

import java.nio.ByteBuffer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import scala.concurrent.ExecutionContext
import scala.concurrent.duration.Duration
import scala.util.{Success, Failure}

import org.http4s.util.CaseInsensitiveString._
import org.http4s.syntax.string._

private class Http2NodeStage(streamId: Int,
timeout: Duration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import org.http4s.blaze.http.websocket.{WSFrameAggregator, WebSocketDecoder}
import org.http4s.websocket.WebsocketHandshake
import org.http4s.blaze.pipeline.LeafBuilder
import org.http4s.blaze.websocket.Http4sWSStage
import org.http4s.util.CaseInsensitiveString._
import org.http4s.syntax.string._

import scala.util.{Failure, Success}
import scala.concurrent.Future
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import org.http4s.{headers => H, _}
import org.http4s.Status._
import org.http4s.blaze._
import org.http4s.blaze.pipeline.{Command => Cmd}
import org.http4s.util.CaseInsensitiveString._
import org.specs2.mutable.Specification
import org.specs2.specification.core.Fragment

import scala.concurrent.{Await, Future}
Expand All @@ -24,7 +22,7 @@ import scala.concurrent.ExecutionContext.Implicits.global

import scodec.bits.ByteVector

class Http1ServerStageSpec extends Specification {
class Http1ServerStageSpec extends Http4sSpec {
def makeString(b: ByteBuffer): String = {
val p = b.position()
val a = new Array[Byte](b.remaining())
Expand Down
2 changes: 1 addition & 1 deletion client/src/main/scala/org/http4s/client/Client.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package client

import java.util.concurrent.atomic.AtomicBoolean
import org.http4s.headers.{Accept, MediaRangeAndQValue}
import org.http4s.Status.ResponseClass.Successful
import org.http4s.Status.Successful
import scala.util.control.NoStackTrace

import java.io.IOException
Expand Down
2 changes: 1 addition & 1 deletion client/src/main/scala/org/http4s/client/RequestKey.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package org.http4s
package client

import org.http4s.Uri.{Authority, Scheme}
import org.http4s.util.string._
import org.http4s.syntax.string._

/** Represents a key for requests that can conceivably share a [[Connection]]. */
final case class RequestKey(scheme: Scheme, authority: Authority)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package middleware

import org.http4s.Method._
import org.http4s.headers._
import org.http4s.util.string._
import org.http4s.syntax.string._
import scalaz._
import scalaz.concurrent.Task
import scalaz.stream.Process._
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import java.nio.charset.StandardCharsets
import javax.crypto

import org.http4s.headers.Authorization
import org.http4s.util.string._
import org.http4s.syntax.string._
import org.http4s.util.UrlCodingUtils

import scala.collection.mutable.ListBuffer
Expand Down
3 changes: 1 addition & 2 deletions core/src/main/scala/org/http4s/AuthScheme.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.http4s

import util.string._

import org.http4s.syntax.string._

object AuthScheme {
val Basic = "Basic".ci
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/org/http4s/CacheDirective.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ package org.http4s
import scala.Product
import org.http4s.util.{CaseInsensitiveString, Writer, Renderable}
import scala.concurrent.duration.Duration
import util.string._
import org.http4s.syntax.string._

sealed trait CacheDirective extends Product with Renderable {
val name = productPrefix.replace("$minus", "-").ci
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/org/http4s/ContentCoding.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
package org.http4s

import org.http4s.util._
import string._
import org.http4s.syntax.string._

final case class ContentCoding (coding: CaseInsensitiveString, qValue: QValue = QValue.One) extends HasQValue with Renderable {
def withQValue(q: QValue): ContentCoding = copy(coding, q)
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/org/http4s/Header.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ package org.http4s
import org.http4s.util.NonEmptyList

import org.http4s.util.{Writer, CaseInsensitiveString, Renderable, StringWriter}
import org.http4s.util.string._
import org.http4s.syntax.string._

import scala.util.hashing.MurmurHash3

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/org/http4s/HeaderKey.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import org.http4s.util.NonEmptyList
import scala.annotation.tailrec
import scala.reflect.ClassTag
import org.http4s.util.CaseInsensitiveString
import org.http4s.util.string._
import org.http4s.syntax.string._

sealed trait HeaderKey {
type HeaderT <: Header
Expand Down
8 changes: 1 addition & 7 deletions core/src/main/scala/org/http4s/Http4s.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package org.http4s
trait Http4s
extends Http4sInstances
with Http4sFunctions
with Http4sSyntax
with syntax.AllSyntax

object Http4s extends Http4s

Expand All @@ -23,9 +23,3 @@ trait Http4sFunctions
with UriFunctions

object Http4sFunctions extends Http4sFunctions

trait Http4sSyntax
extends util.CaseInsensitiveStringSyntax
with MessageSyntax

object Http4sSyntax extends Http4sSyntax
53 changes: 6 additions & 47 deletions core/src/main/scala/org/http4s/MessageSyntax.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,52 +6,11 @@ import scalaz.concurrent.Task
object MessageSyntax extends MessageSyntax

trait MessageSyntax {
implicit def requestSyntax(req: Task[Request]): TaskRequestOps = new TaskRequestOps(req)
@deprecated("Moved to org.http4s.syntax.TaskRequestSyntax", "0.16")
implicit def requestSyntax(req: Task[Request]): syntax.TaskRequestOps =
new syntax.TaskRequestOps(req)

implicit def responseSyntax(resp: Task[Response]): TaskResponseOps = new TaskResponseOps(resp)
}

trait TaskMessageOps[M <: Message] extends Any with MessageOps {
type Self = Task[M#Self]

def self: Task[M]

def transformHeaders(f: Headers => Headers): Self =
self.map(_.transformHeaders(f))

/** Add a body to the message
* @see [[Message]]
*/
def withBody[T](b: T)(implicit w: EntityEncoder[T]): Self = self.flatMap(_.withBody(b)(w))

/** Generates a new message object with the specified key/value pair appended to the [[org.http4s.AttributeMap]]
*
* @param key [[AttributeKey]] with which to associate the value
* @param value value associated with the key
* @tparam A type of the value to store
* @return a new message object with the key/value pair appended
*/
override def withAttribute[A](key: AttributeKey[A], value: A): Self = self.map(_.withAttribute(key, value))

/** Decode the [[Message]] to the specified type
*
* @param decoder [[EntityDecoder]] used to decode the [[Message]]
* @tparam T type of the result
* @return the `Task` which will generate the `ParseFailure\/T`
*/
override def attemptAs[T](implicit decoder: EntityDecoder[T]): DecodeResult[T] = EitherT(self.flatMap { msg =>
decoder.decode(msg, false).run
})
}

final class TaskRequestOps(val self: Task[Request]) extends AnyVal with TaskMessageOps[Request] with RequestOps {
def decodeWith[A](decoder: EntityDecoder[A], strict: Boolean)(f: A => Task[Response]): Task[Response] =
self.flatMap(_.decodeWith(decoder, strict)(f))

def withPathInfo(pi: String): Task[Request] =
self.map(_.withPathInfo(pi))
}

final class TaskResponseOps(val self: Task[Response]) extends AnyVal with TaskMessageOps[Response] with ResponseOps {
override def withStatus(status: Status): Self = self.map(_.withStatus(status))
@deprecated("Moved to org.http4s.syntax.TaskResponseSyntax", "0.16")
implicit def responseSyntax(resp: Task[Response]): syntax.TaskResponseOps =
new syntax.TaskResponseOps(resp)
}
31 changes: 21 additions & 10 deletions core/src/main/scala/org/http4s/Status.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ import org.http4s.util.Renderable
final case class Status private (code: Int)(val reason: String = "", val isEntityAllowed: Boolean = true) extends Ordered[Status] with Renderable {
// scalastyle:off magic.number
val responseClass: ResponseClass =
if (code < 200) ResponseClass.Informational
else if (code < 300) ResponseClass.Successful
else if (code < 400) ResponseClass.Redirection
else if (code < 500) ResponseClass.ClientError
else ResponseClass.ServerError
if (code < 200) Status.Informational
else if (code < 300) Status.Successful
else if (code < 400) Status.Redirection
else if (code < 500) Status.ClientError
else Status.ServerError
// scalastyle:on magic.number

def compare(that: Status): Int = code - that.code
Expand All @@ -49,12 +49,23 @@ object Status {
if (resp.status.responseClass == this) Some(resp) else None
}

case object Informational extends ResponseClass { val isSuccess = true }
case object Successful extends ResponseClass { val isSuccess = true }
case object Redirection extends ResponseClass { val isSuccess = true }
case object ClientError extends ResponseClass { val isSuccess = false }
case object ServerError extends ResponseClass { val isSuccess = false }

object ResponseClass {
case object Informational extends ResponseClass { val isSuccess = true }
case object Successful extends ResponseClass { val isSuccess = true }
case object Redirection extends ResponseClass { val isSuccess = true }
case object ClientError extends ResponseClass { val isSuccess = false }
case object ServerError extends ResponseClass { val isSuccess = false }
@deprecated("Moved to org.http4s.Status.Informational", "0.16")
val Informational = Status.Informational
@deprecated("Moved to org.http4s.Status.Successful", "0.16")
val Successful = Status.Successful
@deprecated("Moved to org.http4s.Status.Redirection", "0.16")
val Redirection = Status.Informational
@deprecated("Moved to org.http4s.Status.ClientError", "0.16")
val ClientError = Status.Informational
@deprecated("Moved to org.http4s.Status.ServerError", "0.16")
val ServerError = Status.Informational
}

private def mkStatus(code: Int, reason: String = ""): ParseResult[Status] =
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/org/http4s/TransferCoding.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
package org.http4s

import org.http4s.util._
import org.http4s.util.string._
import org.http4s.syntax.string._

final case class TransferCoding private (coding: CaseInsensitiveString) extends Renderable {
override def render(writer: Writer): writer.type = writer.append(coding.toString)
Expand Down
5 changes: 2 additions & 3 deletions core/src/main/scala/org/http4s/Uri.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import macrocompat.bundle
import org.http4s.Uri._
import org.http4s.parser.{ ScalazDeliverySchemes, RequestUriParser }
import org.http4s.util.{ Writer, Renderable, CaseInsensitiveString, UrlCodingUtils }
import org.http4s.util.string.ToCaseInsensitiveStringSyntax
import org.http4s.util.option.ToOptionOps
import org.http4s.syntax.string._


/** Representation of the [[Request]] URI
Expand Down Expand Up @@ -213,7 +212,7 @@ trait UriFunctions {
case (Uri(s,a,p,q,_), Uri(_,_,"",Query.empty,f)) => Uri(s,a,p,q,f)
case (Uri(s,a,p,_,_), Uri(_,_,"",q,f)) => Uri(s,a,p,q,f)
case (Uri(s,a,bp,_,_), Uri(_,_,p,q,f)) =>
if (p.headOption.contains('/')) Uri(s,a,p,q,f)
if (p.headOption.fold(false)(_ == '/')) Uri(s,a,p,q,f)
else Uri(s,a,merge(bp,p),q,f)
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/org/http4s/headers/Connection.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package headers

import org.http4s.parser.HttpHeaderParser
import org.http4s.util.{Writer, CaseInsensitiveString}
import org.http4s.util.string._
import org.http4s.syntax.string._

import org.http4s.util.NonEmptyList

Expand Down
3 changes: 3 additions & 0 deletions core/src/main/scala/org/http4s/implicits/package.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package org.http4s

object implicits extends syntax.AllSyntax
5 changes: 5 additions & 0 deletions core/src/main/scala/org/http4s/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,9 @@ package object http4s { // scalastyle:ignore

/** A stream of server-sent events */
type EventStream = Process[Task, ServerSentEvent]

@deprecated("Moved to org.http4s.syntax.AllSyntax", "0.16")
type Http4sSyntax = syntax.AllSyntax
@deprecated("Moved to org.http4s.syntax.all", "0.16")
val Http4sSyntax = syntax.all
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ package parser

import org.parboiled2.{Rule0, Rule1, ParserInput}
import org.http4s.headers.Authorization
import org.http4s.util.CaseInsensitiveString._
import org.http4s.syntax.string._

private[parser] trait AuthorizationHeader {
def AUTHORIZATION(value: String): ParseResult[`Authorization`] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import scala.concurrent.duration._
import org.parboiled2.{Rule1, ParserInput}
import org.http4s.headers.`Cache-Control`
import org.http4s.CacheDirective._
import org.http4s.util.string._
import org.http4s.syntax.string._

private[parser] trait CacheControlHeader {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import org.http4s.headers._
import org.http4s.util.CaseInsensitiveString

import Header.Parsed
import org.http4s.util.string._
import org.http4s.syntax.string._


object HttpHeaderParser extends SimpleHeaders
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/org/http4s/parser/Rfc3986Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import java.nio.charset.Charset
import java.net.URLDecoder
import shapeless.HNil
import scalaz.syntax.std.option._
import org.http4s.util.CaseInsensitiveString._
import org.http4s.{ Query => Q }
import org.http4s.syntax.string._

private[parser] trait Rfc3986Parser { this: Parser =>
// scalastyle:off public.methods.have.type
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/org/http4s/parser/SimpleHeaders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ import java.net.InetAddress
import java.time.Instant

import org.http4s.headers.ETag.EntityTag
import org.http4s.util.CaseInsensitiveString._
import org.parboiled2.Rule1
import org.http4s.syntax.string._
import org.http4s.util.NonEmptyList
import org.parboiled2.Rule1

/**
* parser rules for all headers that can be parsed with one simple rule
Expand Down
8 changes: 8 additions & 0 deletions core/src/main/scala/org/http4s/syntax/AllSyntax.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.http4s
package syntax

trait AllSyntax extends AnyRef
with ServiceSyntax
with StringSyntax
with TaskResponseSyntax
with TaskRequestSyntax
14 changes: 14 additions & 0 deletions core/src/main/scala/org/http4s/syntax/ServiceSyntax.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.http4s
package syntax

import scalaz.concurrent.Task

trait ServiceSyntax {
implicit def http4sServiceSyntax[A, B](service: Service[A, B]): ServiceOps[A, B] =
new ServiceOps[A, B](service)
}

final class ServiceOps[A, B](self: Service[A, B]) {
def orNotFound(a: A)(implicit ev: B <:< MaybeResponse): Task[Response] =
self.run(a).map(_.orNotFound)
}
Loading

0 comments on commit 57f1727

Please sign in to comment.