SHARE
TWEET

Untitled

a guest Jun 16th, 2019 43 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. defmodule Percussion.Dispatcher do
  2.   @moduledoc """
  3.   TODO: write documentation.
  4.   """
  5.  
  6.   alias Percussion.Dispatcher
  7.   alias Percussion.Pipeline
  8.   alias Percussion.Request
  9.  
  10.   @typedoc "Function which will be called from this dispatcher."
  11.   @type call :: Request.transform()
  12.  
  13.   @typedoc "List of match that this dispatcher matches on."
  14.   @type match :: [String.t()]
  15.  
  16.   @typedoc "Preprocessing steps before calling the dispatcher call."
  17.   @type pipe :: [Request.transform()]
  18.  
  19.   @type t :: %Dispatcher{
  20.           call: call,
  21.           match: match,
  22.           pipe: pipe
  23.         }
  24.  
  25.   defstruct [:match, :call, pipe: []]
  26.  
  27.   @doc """
  28.   Creates a `t:Percussion.Dispatcher.t/0` specification for the given command.
  29.   """
  30.   @spec command(Request.transform(), Keyword.t()) :: t
  31.   def command(call, options \\ []) do
  32.     %Dispatcher{
  33.       call: call,
  34.       match: options[:match] || [],
  35.       pipe: options[:pipe] || []
  36.     }
  37.   end
  38.  
  39.   @doc """
  40.   Creates a `t:Percussion.Dispatcher.t/0` specification for the given router.
  41.   """
  42.   @spec router([t], [Request.transform()]) :: t
  43.   def router(routes, pipe \\ []) do
  44.     table = routing_table(routes)
  45.  
  46.     dispatch = fn request ->
  47.       dispatch(table[request.invoked_with], request)
  48.     end
  49.  
  50.     %Dispatcher{
  51.       call: dispatch,
  52.       match: Map.keys(table),
  53.       pipe: pipe
  54.     }
  55.   end
  56.  
  57.   defp routing_table(routes) do
  58.     for dispatcher <- routes do
  59.       Enum.map(dispatcher.match, fn match -> {match, dispatcher} end)
  60.     end
  61.     |> Enum.concat()
  62.     |> Enum.into(%{})
  63.   end
  64.  
  65.   @doc """
  66.   Dispatches.
  67.   """
  68.   @spec dispatch(t, Request.t()) :: Request.t()
  69.   def dispatch(%Dispatcher{pipe: pipe, call: call}, request) do
  70.     pipe
  71.     |> Pipeline.fold(request)
  72.     |> Request.map(call)
  73.   end
  74. end
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top