zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

status.ex (4862B)


      1 defmodule Plug.Conn.Status do
      2   @moduledoc """
      3   Conveniences for working with status codes.
      4   """
      5 
      6   custom_statuses = Application.compile_env(:plug, :statuses, %{})
      7 
      8   statuses = %{
      9     100 => "Continue",
     10     101 => "Switching Protocols",
     11     102 => "Processing",
     12     103 => "Early Hints",
     13     200 => "OK",
     14     201 => "Created",
     15     202 => "Accepted",
     16     203 => "Non-Authoritative Information",
     17     204 => "No Content",
     18     205 => "Reset Content",
     19     206 => "Partial Content",
     20     207 => "Multi-Status",
     21     208 => "Already Reported",
     22     226 => "IM Used",
     23     300 => "Multiple Choices",
     24     301 => "Moved Permanently",
     25     302 => "Found",
     26     303 => "See Other",
     27     304 => "Not Modified",
     28     305 => "Use Proxy",
     29     306 => "Switch Proxy",
     30     307 => "Temporary Redirect",
     31     308 => "Permanent Redirect",
     32     400 => "Bad Request",
     33     401 => "Unauthorized",
     34     402 => "Payment Required",
     35     403 => "Forbidden",
     36     404 => "Not Found",
     37     405 => "Method Not Allowed",
     38     406 => "Not Acceptable",
     39     407 => "Proxy Authentication Required",
     40     408 => "Request Timeout",
     41     409 => "Conflict",
     42     410 => "Gone",
     43     411 => "Length Required",
     44     412 => "Precondition Failed",
     45     413 => "Request Entity Too Large",
     46     414 => "Request-URI Too Long",
     47     415 => "Unsupported Media Type",
     48     416 => "Requested Range Not Satisfiable",
     49     417 => "Expectation Failed",
     50     418 => "I'm a teapot",
     51     421 => "Misdirected Request",
     52     422 => "Unprocessable Entity",
     53     423 => "Locked",
     54     424 => "Failed Dependency",
     55     425 => "Too Early",
     56     426 => "Upgrade Required",
     57     428 => "Precondition Required",
     58     429 => "Too Many Requests",
     59     431 => "Request Header Fields Too Large",
     60     451 => "Unavailable For Legal Reasons",
     61     500 => "Internal Server Error",
     62     501 => "Not Implemented",
     63     502 => "Bad Gateway",
     64     503 => "Service Unavailable",
     65     504 => "Gateway Timeout",
     66     505 => "HTTP Version Not Supported",
     67     506 => "Variant Also Negotiates",
     68     507 => "Insufficient Storage",
     69     508 => "Loop Detected",
     70     510 => "Not Extended",
     71     511 => "Network Authentication Required"
     72   }
     73 
     74   reason_phrase_to_atom = fn reason_phrase ->
     75     reason_phrase
     76     |> String.downcase()
     77     |> String.replace("'", "")
     78     |> String.replace(~r/[^a-z0-9]/, "_")
     79     |> String.to_atom()
     80   end
     81 
     82   status_map_to_doc = fn statuses ->
     83     statuses
     84     |> Enum.sort_by(&elem(&1, 0))
     85     |> Enum.map(fn {code, reason_phrase} ->
     86       atom = reason_phrase_to_atom.(reason_phrase)
     87       "  * `#{inspect(atom)}` - #{code}\n"
     88     end)
     89   end
     90 
     91   custom_status_doc =
     92     if custom_statuses != %{} do
     93       """
     94       ## Custom status codes
     95 
     96       #{status_map_to_doc.(custom_statuses)}
     97       """
     98     end
     99 
    100   @doc """
    101   Returns the status code given an integer or a known atom.
    102 
    103   ## Known status codes
    104 
    105   The following status codes can be given as atoms with their
    106   respective value shown next:
    107 
    108   #{status_map_to_doc.(statuses)}
    109   #{custom_status_doc}
    110   """
    111   @spec code(integer | atom) :: integer
    112   def code(integer_or_atom)
    113 
    114   def code(integer) when integer in 100..999 do
    115     integer
    116   end
    117 
    118   for {code, reason_phrase} <- statuses do
    119     atom = reason_phrase_to_atom.(reason_phrase)
    120     def code(unquote(atom)), do: unquote(code)
    121   end
    122 
    123   # This ensures that both the default and custom statuses will work
    124   for {code, reason_phrase} <- custom_statuses do
    125     atom = reason_phrase_to_atom.(reason_phrase)
    126     def code(unquote(atom)), do: unquote(code)
    127   end
    128 
    129   @doc """
    130   Returns the atom for given integer.
    131 
    132   See `code/1` for the mapping.
    133   """
    134   @spec reason_atom(integer) :: atom
    135   def reason_atom(code)
    136 
    137   for {code, reason_phrase} <- Map.merge(statuses, custom_statuses) do
    138     atom = reason_phrase_to_atom.(reason_phrase)
    139     def reason_atom(unquote(code)), do: unquote(atom)
    140   end
    141 
    142   def reason_atom(code) do
    143     raise ArgumentError, "unknown status code #{inspect(code)}"
    144   end
    145 
    146   @spec reason_phrase(integer) :: String.t()
    147   def reason_phrase(integer)
    148 
    149   for {code, phrase} <- Map.merge(statuses, custom_statuses) do
    150     def reason_phrase(unquote(code)), do: unquote(phrase)
    151   end
    152 
    153   def reason_phrase(code) do
    154     raise ArgumentError, """
    155     unknown status code #{inspect(code)}
    156 
    157     Custom codes can be defined in the configuration for the :plug application,
    158     under the :statuses key (which contains a map of status codes as keys and
    159     reason phrases as values). For example:
    160 
    161         config :plug, :statuses, %{998 => "Not An RFC Status Code"}
    162 
    163     After defining the config for custom statuses, Plug must be recompiled for
    164     the changes to take place using:
    165 
    166         MIX_ENV=dev mix deps.clean plug --build
    167 
    168     Doing this will allow the use of the integer status code 998 as
    169     well as the atom :unavailable_for_legal_reasons in many Plug functions.
    170     For example:
    171 
    172         put_status(conn, :not_an_rfc_status_code)
    173     """
    174   end
    175 end