Use macro in Elixir's HTTPoison

Gao
使用了HTTPoison来创建一个http请求代理后, 当前有一个问题.处理http请求响应有太多的重复代码, 所以需要一个方式来优化重复问题. 这里, 尝试了之前很少使用的macro来解决. ## 关于macro Elixir是基于beam上的语言, 语言上很多的statement实际上都是macro, 比如基本的if,else 在Elixir中,允许直接创建和访问`abstract syntax tree` (`AST`), 可以使用 `quota` and `unquota`来操作 简单示例 ```elixir iex> denominator = 2 2 iex> quote do: divide(42, denominator) {:divide, [], [42, {:denominator, [], Elixir}]} iex> quote do: divide(42, unquote(denominator)) {:divide, [], [42, 2]} ``` 简单示例, 如何使用macro ```elixir defmodule Logger do defmacro log(msg) do if Application.get_env(:logger, :enabled) do quote do IO.puts("Logged message: #{unquote(msg)}") end end end end defmodule Example do require Logger def test do Logger.log("This is a log message") end end ``` **解释**: 这里使用宏是因为macro是在编译时展开的, 如果配置没有启用loger, 则不会展开对应macro, 程序中就不会有对应代码. ## 使用macro来处理HTTPoison的response请求 代码 ```elixir @spec process_result(HTTPoison.Response.t(), String.t()) :: {:ok, t} | {:error, t} defmacro process_result(result) do quote do case unquote(result) do {:ok, %HTTPoison.Response{ body: data, status_code: status_code, request: %HTTPoison.Request{url: request_url} }} when status_code >= 200 and status_code < 300 -> IO.inspect({"Access Success", status_code, request_url}) {:ok, data} {:ok, %HTTPoison.Response{ body: data, status_code: 401, request: %HTTPoison.Request{url: request_url} }} -> IO.inspect({"Unauthorized Error", 401, request_url}) {:error, data} {:ok, %HTTPoison.Response{ body: body, status_code: status_code, request: %HTTPoison.Request{url: request_url} }} when status_code >= 400 and status_code < 500 -> IO.inspect({"Client Error", status_code, request_url, body}) {:error, body} {:ok, %HTTPoison.Response{ body: body, status_code: status_code, request: %HTTPoison.Request{url: request_url} }} when status_code >= 500 -> IO.inspect({"Server Error", status_code, request_url, body}) {:error, body} {:error, %HTTPoison.Error{reason: reason} = error} -> IO.inspect({"HTTPoison.Error", error}) {:error, reason} end end end ``` 简单的来处理HTTPoison的Reponse, 添加对应处理逻辑