<commit_before>
defmodule Ewebmachine.Builder.Handlers do
  @moduledoc """
  `use` this  module will `use Plug.Builder` (so a plug pipeline
  described with the `plug module_or_function_plug` macro), but gives
  you an `:add_handler` local function plug which adds to the conn
  the locally defined ewebmachine handlers (see `Ewebmachine.Handlers`).

  So : 

  - Construct your automate decision handler through multiple `:add_handler` plugs
  - Pipe the plug `Ewebmachine.Plug.Run` to run the HTTP automate which
    will call these handlers to take decisions. 
  - Pipe the plug `Ewebmachine.Plug.Send` to send and halt any conn previsously passed
    through an automate run.
  
  To define handlers, use the following helpers :

  - the handler specific macros (like `Ewebmachine.Builder.Handlers.resource_exists/1`)
  - the macro `defh/2` to define any helpers, usefull for body
    producing handlers or to have multiple function clauses 
  - in handler implementation `conn` and `state` binding are available
  - the response of the handler implementation is wrapped, so that
    returning `:my_response` is the same as returning `{:my_response,conn,state}`

  Below a full example :

  ```
  defmodule MyJSONApi do 
    use Ewebmachine.Builder.Handlers
    plug :cors
    plug :add_handlers, init: %{}

    content_types_provided do: ["application/json": :to_json]
    defh to_json, do: Poison.encode!(state[:json_obj])

    defp cors(conn,_), do: 
      put_resp_header(conn,"Access-Control-Allow-Origin","*")
  end

  defmodule GetUser do 
    use Ewebmachine.Builder.Handlers
    plug MyJSONApi
    plug :add_handlers
    plug Ewebmachine.Plug.Run
    plug Ewebmachine.Plug.Send
    resource_exists do:
      pass( !is_nil(user=DB.User.get(conn.params["q"])), json_obj: user)
  end
  defmodule GetOrder do 
    use Ewebmachine.Builder.Handlers
    plug MyJSONApi
    plug :add_handlers
    plug Ewebmachine.Plug.Run
    plug Ewebmachine.Plug.Send
    resource_exists do:
      pass(!is_nil(order=DB.Order.get(conn.params["q"])), json_obj: order)
  end

  defmodule API do
    use Plug.Router
    plug :match 
    plug :dispatch

    get "/get/user", do: GetUser.call(conn,[])
    get "/get/order", do: GetOrder.call(conn,[])
  end
  ```
  """
  defmacro __before_compile__(_env) do
    quote do
      defp add_handlers(conn, opts) do
        if opts && (init=opts[:init]), do:
          conn = put_private(conn,:machine_init,init)
        Plug.Conn.put_private(conn,:resource_handlers,
          Enum.into(@resource_handlers,conn.private[:resource_handlers] || %{}))<commit_msg>[1.3.x] suppress shadowing in Ewebmachine.Build.Handlers init<commit_after>
defmodule Ewebmachine.Builder.Handlers do
  @moduledoc """
  `use` this  module will `use Plug.Builder` (so a plug pipeline
  described with the `plug module_or_function_plug` macro), but gives
  you an `:add_handler` local function plug which adds to the conn
  the locally defined ewebmachine handlers (see `Ewebmachine.Handlers`).

  So : 

  - Construct your automate decision handler through multiple `:add_handler` plugs
  - Pipe the plug `Ewebmachine.Plug.Run` to run the HTTP automate which
    will call these handlers to take decisions. 
  - Pipe the plug `Ewebmachine.Plug.Send` to send and halt any conn previsously passed
    through an automate run.
  
  To define handlers, use the following helpers :

  - the handler specific macros (like `Ewebmachine.Builder.Handlers.resource_exists/1`)
  - the macro `defh/2` to define any helpers, usefull for body
    producing handlers or to have multiple function clauses 
  - in handler implementation `conn` and `state` binding are available
  - the response of the handler implementation is wrapped, so that
    returning `:my_response` is the same as returning `{:my_response,conn,state}`

  Below a full example :

  ```
  defmodule MyJSONApi do 
    use Ewebmachine.Builder.Handlers
    plug :cors
    plug :add_handlers, init: %{}

    content_types_provided do: ["application/json": :to_json]
    defh to_json, do: Poison.encode!(state[:json_obj])

    defp cors(conn,_), do: 
      put_resp_header(conn,"Access-Control-Allow-Origin","*")
  end

  defmodule GetUser do 
    use Ewebmachine.Builder.Handlers
    plug MyJSONApi
    plug :add_handlers
    plug Ewebmachine.Plug.Run
    plug Ewebmachine.Plug.Send
    resource_exists do:
      pass( !is_nil(user=DB.User.get(conn.params["q"])), json_obj: user)
  end
  defmodule GetOrder do 
    use Ewebmachine.Builder.Handlers
    plug MyJSONApi
    plug :add_handlers
    plug Ewebmachine.Plug.Run
    plug Ewebmachine.Plug.Send
    resource_exists do:
      pass(!is_nil(order=DB.Order.get(conn.params["q"])), json_obj: order)
  end

  defmodule API do
    use Plug.Router
    plug :match 
    plug :dispatch

    get "/get/user", do: GetUser.call(conn,[])
    get "/get/order", do: GetOrder.call(conn,[])
    end
  ```
  """
  defmacro __before_compile__(_env) do
    quote do
      defp add_handlers(conn, opts) do
	init = opts[:init]
        conn = if opts && init,
	  do: put_private(conn, :machine_init, init),
	  else: conn
        Plug.Conn.put_private(conn, :resource_handlers,
          Enum.into(@resource_handlers, conn.private[:resource_handlers] || %{}))
{'fraction_non_alphanumeric': 0.09641768292682927, 'fraction_numerical': 0.0011432926829268292, 'mean_word_length': 3.548526863084922, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7437716', 'n_tokens_mistral': 1694, 'n_tokens_neox': 1649, 'n_words': 499}