Current section
Files
Jump to
Current section
Files
lib/router.ex
defmodule Spotter.Router do
@moduledoc """
Router struct that handles the endpoints and makes dispatching.
"""
@typep default_endpoint_struct :: Spotter.Endpoint.Plain | Spotter.Endpoint.Dynamic
@typep default_endpoint_args :: {String.t, [String.t]}
@typep custom_endpoint_args :: {String.t, [String.t], UserDefined}
@typep dispatch_result :: default_endpoint_struct | UserDefined | nil
@doc """
Defines the router struct.
* :endpoints - List of endpoints, where each endpoint represented as the
`Spotter.Endpoint.Plain` or the `Spotter.Endpoint.Dynamic` or a Used Defined structure,
derived from the `Spotter.Endpoint.Base`.
"""
@enforce_keys [:endpoints]
defstruct [:endpoints]
# Converts a passed tuple to the custom endpoints structure
@spec convert_to_endpoint(custom_endpoint_args) :: UserDefined
defp convert_to_endpoint({path, permissions, custom_structure}) do
custom_structure.new(path, permissions)
end
# Converts a passed tuple to the default endpoint structure
@spec convert_to_endpoint(default_endpoint_args) :: default_endpoint_struct
defp convert_to_endpoint({path, permissions}) do
case String.contains?(path, ["{", "}"]) do
true -> Spotter.Endpoint.Dynamic.new(path, permissions)
false -> Spotter.Endpoint.Plain.new(path, permissions)
end
end
@doc """
Creates a new router based on the list of tuples. Each tuples represent an
endpoints, that required for pre-processing and validating.
"""
@spec new(endpoints::[default_endpoint_args | custom_endpoint_args]) :: Spotter.Router
def new(endpoints) do
%Spotter.Router{endpoints: Enum.map(endpoints, &(convert_to_endpoint(&1)))}
end
@doc """
Returns an endpoint that matches to the `path` argument. Otherwise returns `nil`.
"""
@spec dispatch(router::Spotter.Router, path::Strint.t) :: dispatch_result
def dispatch(router, path) do
Enum.find(router.endpoints, fn(endpoint) -> endpoint.__struct__.match(endpoint, path) end)
end
end