1
package hammock
2

3
import cats.syntax.show._
4
import cats.free.Free
5

6
import hi.Opts
7
import Encoder.ops._
8

9
object Hammock {
10

11
  /** Creates an [[HttpF]] and from the
12
   * [[Method]], [[Uri]], and [[Map[String, String] headers]].  It
13
   * can be later executed via an interpreter.
14
   */
15
  def request(method: Method, uri: Uri, headers: Map[String, String]): Free[HttpF, HttpResponse] = method match {
16 1
    case Method.OPTIONS => Ops.options(uri, headers)
17 1
    case Method.GET     => Ops.get(uri, headers)
18 1
    case Method.HEAD    => Ops.head(uri, headers)
19 1
    case Method.POST    => Ops.post(uri, headers, None)
20 1
    case Method.PUT     => Ops.put(uri, headers, None)
21 1
    case Method.DELETE  => Ops.delete(uri, headers)
22 1
    case Method.TRACE   => Ops.trace(uri, headers)
23 1
    case Method.PATCH   => Ops.patch(uri, headers, None)
24
  }
25

26
  /** similar to [[request]], but you can pass it a
27
   * body when it exists an instance for the [[Encoder]]
28
   * typeclass for the given type [[A]]
29
   */
30
  def request[A: Encoder](
31
      method: Method,
32
      uri: Uri,
33
      headers: Map[String, String],
34
      body: Option[A]): Free[HttpF, HttpResponse] = method match {
35 1
    case Method.OPTIONS => Ops.options(uri, headers)
36 1
    case Method.GET     => Ops.get(uri, headers)
37 1
    case Method.HEAD    => Ops.head(uri, headers)
38 1
    case Method.POST    => Ops.post(uri, headers, body.map(x => x.encode))
39 1
    case Method.PUT     => Ops.put(uri, headers, body.map(x => x.encode))
40 1
    case Method.DELETE  => Ops.delete(uri, headers)
41 1
    case Method.TRACE   => Ops.trace(uri, headers)
42 1
    case Method.PATCH   => Ops.patch(uri, headers, body.map(x => x.encode))
43
  }
44

45
  /** Creates a request value given a [[Method method]], [[Uri uri]], and [[hi.Opts opts]], and suspends it into a [[cats.free.Free]].
46
   *
47
   * Usage:
48
   *
49
   * {{{
50
   * scala> import hammock._, hammock.jvm.Interpreter, hammock.hi._, hammock.hi._, cats._, cats.implicits._, scala.util.Try
51
   * import hammock._
52
   * import hammock.jvm.Interpreter
53
   * import hammock.hi._
54
   * import cats._
55
   * import cats.implicits._
56
   * import scala.util.Try
57
   *
58
   * scala> val opts = (header("X-Test" -> "works!") >>> auth(Auth.BasicAuth("user", "pass")) >>> cookie(Cookie("key", "value")))(Opts.empty)
59
   * opts: hammock.hi.Opts = Opts(Some(BasicAuth(user,pass)),Map(X-Test -> works!),Some(List(Cookie(key,value,None,None,None,None,None,None,None,None))))
60
   *
61
   * scala> val response = Hammock.withOpts(Method.GET, uri"http://httpbin.org/get", opts)
62
   * response: Free[HttpF, hammock.HttpResponse] = Free(...)
63
   * }}}
64
   *
65
   */
66
  def withOpts(method: Method, uri: Uri, opts: Opts): Free[HttpF, HttpResponse] =
67 1
    request(method, uri, constructHeaders(opts))
68

69
  /** Variant of [[withOpts]] methods that also takes an optional body
70
   * of a request. There should be a Encoder instance for the body type
71
   * for this to work.
72
   *
73
   * @see Hammock.withOpts
74
   */
75
  def withOpts[A: Encoder](method: Method, uri: Uri, opts: Opts, body: Option[A]): Free[HttpF, HttpResponse] =
76 0
    request(method, uri, constructHeaders(opts), body)
77

78
  /** Creates an OPTIONS request to the given [[Uri uri]] and [[hi.Opts opts]].
79
   *
80
   * {{{
81
   * scala> import hammock._, hammock.jvm.Interpreter, hammock.hi._, hammock.hi._, cats._, cats.implicits._, scala.util.Try
82
   * import hammock._
83
   * import hammock.jvm.Interpreter
84
   * import hammock.hi._
85
   * import cats._
86
   * import cats.implicits._
87
   * import scala.util.Try
88
   *
89
   * scala> val opts = (header("X-Test" -> "works!") >>> auth(Auth.BasicAuth("user", "pass")) >>> cookie(Cookie("key", "value")))(Opts.empty)
90
   * opts: hammock.hi.Opts = Opts(Some(BasicAuth(user,pass)),Map(X-Test -> works!),Some(List(Cookie(key,value,None,None,None,None,None,None,None,None))))
91
   *
92
   * scala> Hammock.optionsWithOpts(uri"http://httpbin.org/get", opts)
93
   * res1: Free[HttpF, hammock.HttpResponse] = Free(...)
94
   * }}}
95
   *
96
   */
97 0
  def optionsWithOpts(uri: Uri, opts: Opts): Free[HttpF, HttpResponse] = withOpts(Method.OPTIONS, uri, opts)
98

99
  /** Creates a GET request to the given [[Uri uri]] and [[hi.Opts opts]].
100
   *
101
   * {{{
102
   * scala> import hammock._, hammock.jvm.Interpreter, hammock.hi._, hammock.hi._, cats._, cats.implicits._, scala.util.Try
103
   * import hammock._
104
   * import hammock.jvm.Interpreter
105
   * import hammock.hi._
106
   * import cats._
107
   * import cats.implicits._
108
   * import scala.util.Try
109
   *
110
   * scala> val opts = (header("X-Test" -> "works!") >>> auth(Auth.BasicAuth("user", "pass")) >>> cookie(Cookie("key", "value")))(Opts.empty)
111
   * opts: hammock.hi.Opts = Opts(Some(BasicAuth(user,pass)),Map(X-Test -> works!),Some(List(Cookie(key,value,None,None,None,None,None,None,None,None))))
112
   *
113
   * scala> Hammock.getWithOpts(uri"http://httpbin.org/get", opts)
114
   * res1: Free[HttpF, hammock.HttpResponse] = Free(...)
115
   * }}}
116
   *
117
   */
118 1
  def getWithOpts(uri: Uri, opts: Opts): Free[HttpF, HttpResponse] = withOpts(Method.GET, uri, opts)
119

120
  /** Creates a HEAD request to the given [[Uri uri]] and [[hi.Opts opts]].
121
   *
122
   * {{{
123
   * import hammock._
124
   * import hammock.jvm.Interpreter
125
   * import hammock.hi._
126
   * import cats._
127
   * import cats.implicits._
128
   * import scala.util.Try
129
   *
130
   * val opts = (header("X-Test" -> "works!") >>> auth(Auth.BasicAuth("user", "pass")) >>> cookie(Cookie("key", "value")))(Opts.empty)
131
   *
132
   * Hammock.headWithOpts(uri"http://httpbin.org/get", opts)
133
   * }}}
134
   *
135
   */
136 0
  def headWithOpts(uri: Uri, opts: Opts): Free[HttpF, HttpResponse] = withOpts(Method.HEAD, uri, opts)
137

138
  /** Creates a POST request to the given [[Uri uri]] and [[hi.Opts opts]].
139
   * It also has an optional body parameter that can be
140
   * used.
141
   *
142
   * {{{
143
   * import hammock._
144
   * import hammock.jvm.Interpreter
145
   * import hammock.hi._
146
   * import cats._
147
   * import cats.implicits._
148
   * import scala.util.Try
149
   *
150
   * val opts = (header("X-Test" -> "works!") >>> auth(Auth.BasicAuth("user", "pass")) >>> cookie(Cookie("key", "value")))(Opts.empty)
151
   *
152
   * implicit val stringEncoder = new Encoder[String] {
153
   *    def encode(s: String) = s
154
   * }
155
   *
156
   * Hammock.postWithOpts(uri"http://httpbin.org/get", opts, Some("""{"body": true}"""))
157
   * }}}
158
   */
159
  def postWithOpts[A: Encoder](uri: Uri, opts: Opts, body: Option[A] = None): Free[HttpF, HttpResponse] =
160 0
    withOpts(Method.POST, uri, opts, body)
161

162
  /** Creates a PUT request to the given [[Uri uri]] and [[hi.Opts opts]].
163
   * It also has an optional body parameter that can be
164
   * used.
165
   *
166
   * {{{
167
   * import hammock._
168
   * import hammock.jvm.Interpreter
169
   * import hammock.hi._
170
   * import cats._
171
   * import cats.implicits._
172
   * import scala.util.Try
173
   *
174
   * val opts = (header("X-Test" -> "works!") >>> auth(Auth.BasicAuth("user", "pass")) >>> cookie(Cookie("key", "value")))(Opts.empty)
175
   *
176
   * implicit val stringEncoder = new Encoder[String] {
177
   *    def encode(s: String) = s
178
   * }
179
   *
180
   * Hammock.postWithOpts(uri"http://httpbin.org/get", opts, Some("""{"body": true}"""))
181
   * }}}
182
   *
183
   */
184
  def putWithOpts[A: Encoder](uri: Uri, opts: Opts, body: Option[A] = None): Free[HttpF, HttpResponse] =
185 0
    withOpts(Method.PUT, uri, opts, body)
186

187
  /** Creates a DELETE request to the given [[Uri uri]] and [[hi.Opts opts]].
188
   *
189
   * {{{
190
   * val opts = (header("X-Test" -> "works!") >>> auth(Auth.BasicAuth("user", "pass")) >>> cookie(Cookie("key", "value")))(Opts.empty)
191
   *
192
   * Hammock.deleteWithOpts(uri"http://httpbin.org/get", opts)
193
   * }}}
194
   *
195
   */
196 0
  def deleteWithOpts(uri: Uri, opts: Opts): Free[HttpF, HttpResponse] = withOpts(Method.DELETE, uri, opts)
197

198
  /** Creates a TRACE request to the given [[Uri uri]] and [[hi.Opts opts]].
199
   *
200
   * {{{
201
   * val opts = (header("X-Test" -> "works!") >>> auth(Auth.BasicAuth("user", "pass")) >>> cookie(Cookie("key", "value")))(Opts.empty)
202
   *
203
   * Hammock.traceWithOpts(uri"http://httpbin.org/get", opts)
204
   * }}}
205
   *
206
   */
207 0
  def traceWithOpts(uri: Uri, opts: Opts): Free[HttpF, HttpResponse] = withOpts(Method.TRACE, uri, opts)
208

209
  /** Creates a PATCH request to the given [[Uri uri]] and [[hi.Opts opts]].
210
    * It also has an optional body parameter that can be
211
    * used.
212
    *
213
    * {{{
214
    * import hammock._
215
    * import hammock.jvm.Interpreter
216
    * import hammock.hi._
217
    * import cats._
218
    * import cats.implicits._
219
    * import scala.util.Try
220
    *
221
    * val opts = (header("X-Test" -> "works!") >>> auth(Auth.BasicAuth("user", "pass")) >>> cookie(Cookie("key", "value")))(Opts.empty)
222
    *
223
    * implicit val stringCodec = new Codec[String] {
224
    *    def encode(s: String) = s
225
    *    def decode(s: String) = Right(s)
226
    * }
227
    *
228
    * Hammock.patchWithOpts(uri"http://httpbin.org/patch", opts, Some("""{"body": true}"""))
229
    * }}}
230
    *
231
    */
232
  def patchWithOpts[A: Codec](uri: Uri, opts: Opts, body: Option[A] = None): Free[HttpF, HttpResponse] =
233 0
    withOpts(Method.PATCH, uri, opts, body)
234

235
  private def constructHeaders(opts: Opts) =
236
    opts.headers ++
237 1
      opts.cookies.map(_.map(cookie => "Cookie" -> cookie.show)).getOrElse(Map()) ++
238 1
      opts.auth.map(auth => Map("Authorization"    -> auth.show)).getOrElse(Map())
239
}

Read our documentation on viewing source code .

Loading