Packages
tesla
0.1.0
1.20.0
1.18.3
1.18.2
1.18.1
1.18.0
1.17.0
1.16.0
1.15.3
1.15.2
1.15.1
1.15.0
1.14.3
1.14.2
1.14.1
1.14.0
1.13.2
1.13.1
1.13.0
1.12.3
1.12.2
1.12.1
1.12.0
1.11.2
1.11.1
1.11.0
1.10.3
1.10.2
1.10.1
1.10.0
1.9.0
1.8.1
retired
1.8.0
1.7.0
1.6.1
1.6.0
1.5.1
1.5.0
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.3
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.1.0
1.0.0
1.0.0-beta.1
0.10.0
0.9.0
0.8.0
0.7.2
0.7.1
0.7.0
0.6.0
0.5.2
0.5.1
0.5.0
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.2.2
0.2.1
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
HTTP client library, with support for middleware and multiple adapters.
Current section
Files
Jump to
Current section
Files
lib/tesla.ex
defmodule Tesla.Env do
defstruct url: "",
method: nil,
status: nil,
headers: %{},
body: nil,
opts: []
end
defmodule Tesla.Builder do
defmacro __using__(_what) do
method_defs = for method <- [:get, :head, :delete, :trace, :options] do
quote do
def unquote(method)(fun, url, opts) when is_function(fun) do
request(fun, unquote(method), url, nil, opts)
end
def unquote(method)(fun, url) when is_function(fun) do
request(fun, unquote(method), url, nil, [])
end
def unquote(method)(url, opts) do
request(unquote(method), url, nil, opts)
end
def unquote(method)(url) do
request(unquote(method), url, nil, [])
end
end
end
method_defs_with_body = for method <- [:post, :put, :patch] do
quote do
def unquote(method)(fun, url, body, opts) when is_function(fun) do
request(fun, unquote(method), url, body, opts)
end
def unquote(method)(fun, url, body) when is_function(fun) do
request(fun, unquote(method), url, body, [])
end
def unquote(method)(url, body, opts) do
request(unquote(method), url, body, opts)
end
def unquote(method)(url, body) do
request(unquote(method), url, body, [])
end
end
end
quote do
unquote(method_defs)
unquote(method_defs_with_body)
defp request(fun, method, url, body, opts) when is_function(fun) do
env = %Tesla.Env{
method: method,
url: url,
body: body,
opts: opts
}
fun.(env, &call_middleware/1)
end
defp request(method, url, body, opts) do
request(fn (env, run) -> run.(env) end, method, url, body, opts)
end
import Tesla.Builder
Module.register_attribute(__MODULE__, :middleware, accumulate: true)
@before_compile Tesla.Builder
end
end
defmacro __before_compile__(env) do
middleware = Module.get_attribute(env.module, :middleware)
reduced = Enum.reduce(middleware, (quote do: call_adapter(env)), fn {mid, args}, acc ->
quote do
unquote(mid).call(env, fn(env) -> unquote(acc) end, unquote(args))
end
end)
quote do
def call_middleware(env) do
unquote(reduced)
end
end
end
def process_adapter_response(env, res) do
case res do
{status, headers, body} ->
%{env | status: status, headers: headers, body: body}
e -> e
end
end
defmacro adapter({:fn, _, _} = ad) do # pattern match for function
quote do
def call_adapter(env) do
Tesla.Builder.process_adapter_response(env, unquote(ad).(env))
end
end
end
defmacro adapter(ad) do
quote do
def call_adapter(env) do
Tesla.Builder.process_adapter_response(env, unquote(ad).call(env))
end
end
end
defmacro with(middleware) do
quote do
@middleware {unquote(middleware), nil}
end
end
defmacro with(middleware, args) do
quote do
@middleware {unquote(middleware), unquote(args)}
end
end
end
defmodule Tesla do
use Tesla.Builder
adapter Tesla.Adapter.Ibrowse
def build_client(stack) do
fn (env, run) ->
f = Enum.reduce(stack, run, fn ({mid, args}, acc) ->
fn (env) -> mid.call(env, fn(e) -> acc.(e) end, args) end
end)
f.(env)
end
end
def start do
Tesla.Adapter.Ibrowse.start
end
end