Advertisement
Guest User

Untitled

a guest
Jun 16th, 2019
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.70 KB | None | 0 0
  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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement