mirror of
https://github.com/mitchell/shortnr.git
synced 2025-12-19 14:07:22 +00:00
Add HTTP wrap func and Text Encodable:
- Refactor HTTP send func - Impl. Text Encodable for URL - Error when url is not found
This commit is contained in:
parent
b699e661e2
commit
1502d10cdc
8 changed files with 84 additions and 41 deletions
|
|
@ -3,13 +3,20 @@ defmodule Shortnr.Transport.HTTP do
|
|||
This module contains functions that can be used to handle HTTP requests and send responses, by
|
||||
manipulating Plug.Conn.
|
||||
"""
|
||||
|
||||
alias Shortnr.Transport
|
||||
import Plug.Conn
|
||||
|
||||
@type error :: {:error, {atom(), String.t()}, Plug.Conn.t()}
|
||||
@type ok_error :: {:ok, term(), Plug.Conn.t()} | error()
|
||||
|
||||
@spec handle(ok_error(), (... -> ok_error())) :: ok_error()
|
||||
@spec wrap(Plug.Conn.t(), term()) :: ok_error
|
||||
def wrap(conn, argument \\ nil)
|
||||
def wrap(conn, nil), do: {:ok, nil, conn}
|
||||
def wrap(conn, {first, _second} = argument) when is_atom(first), do: {:error, argument, conn}
|
||||
def wrap(conn, argument), do: {:ok, argument, conn}
|
||||
|
||||
@spec handle(ok_error(), (term() -> Transport.ok_error()) | (() -> Transport.ok_error())) ::
|
||||
ok_error()
|
||||
def handle(error = {:error, _sub_error, _conn}, _func), do: error
|
||||
|
||||
def handle({:ok, request, conn}, func) when is_function(func, 1) do
|
||||
|
|
@ -29,19 +36,24 @@ defmodule Shortnr.Transport.HTTP do
|
|||
defp convert_error({:invalid_argument, message}, conn),
|
||||
do: {:error, {:bad_request, message}, conn}
|
||||
|
||||
defp convert_error({:not_found, message}, conn),
|
||||
do: {:error, {:not_found, message}, conn}
|
||||
|
||||
defp convert_error(_, conn), do: {:error, {:internal_server_error, "unknown error"}, conn}
|
||||
|
||||
@spec send(ok_error(), atom(), Plug.Conn.t()) :: Plug.Conn.t()
|
||||
def send({:error, {status, body}, _conn}, _success_status, original_conn) do
|
||||
send_resp(original_conn, status_to_code(status), body)
|
||||
@spec send(ok_error(), atom()) :: Plug.Conn.t()
|
||||
def send(ok_error, success_status \\ nil)
|
||||
|
||||
def send({:error, {status, body}, conn}, _success_status) do
|
||||
send_resp(conn, status_to_code(status), body)
|
||||
end
|
||||
|
||||
def send({:ok, body, conn}, :found, _original_conn) do
|
||||
conn = put_resp_header(conn, "Location", URI.to_string(body))
|
||||
send_resp(conn, status_to_code(:found), URI.to_string(body))
|
||||
def send({:ok, location, conn}, :found) do
|
||||
conn = put_resp_header(conn, "Location", location)
|
||||
send_resp(conn, status_to_code(:found), location)
|
||||
end
|
||||
|
||||
def send({:ok, body, conn}, success_status, _original_conn) do
|
||||
def send({:ok, body, conn}, success_status) do
|
||||
send_resp(conn, status_to_code(success_status), body)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ defmodule Shortnr.Transport.Text do
|
|||
|
||||
import Plug.Conn
|
||||
alias Shortnr.Transport.HTTP
|
||||
alias Shortnr.URL
|
||||
alias Shortnr.Transport.Text.Encodable
|
||||
|
||||
@spec decode_request(Plug.Conn.t()) :: HTTP.ok_error()
|
||||
def decode_request(conn) do
|
||||
|
|
@ -24,11 +24,20 @@ defmodule Shortnr.Transport.Text do
|
|||
{:ok, for(item <- body, into: "", do: "#{item}\n"), conn}
|
||||
end
|
||||
|
||||
def encode_response({:ok, %URL{url: url}, conn}) do
|
||||
{:ok, url, conn}
|
||||
end
|
||||
|
||||
def encode_response({:ok, body, conn}) do
|
||||
{:ok, "#{body}", conn}
|
||||
{:ok, Encodable.encode(body), conn}
|
||||
end
|
||||
end
|
||||
|
||||
defprotocol Shortnr.Transport.Text.Encodable do
|
||||
@moduledoc """
|
||||
Implement this protocol for your type if you would like to text encode it.
|
||||
"""
|
||||
|
||||
@fallback_to_any true
|
||||
def encode(encodable)
|
||||
end
|
||||
|
||||
defimpl Shortnr.Transport.Text.Encodable, for: Any do
|
||||
def encode(encodable), do: to_string(encodable)
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue