defmodule PingPong.Notification do
@moduledoc """
Normalizes notification tuples before dispatching.
This module is used by `PingPong.send_multiple/1` and is also useful when a
notification has already been represented as `{service, payload, options}`.
It validates the tuple shape before delegating to `PingPong.send/3` or
`PingPong.send_async/3`.
"""
@doc """
Sends a notification tuple with the requested delivery mode.
Valid notifications are three-element tuples:
{service, payload, options}
The `service` must be an atom, and both `payload` and `options` must be maps.
## Examples
iex> PingPong.Notification.send_notification({:mock, %{message: "Ping!"}, %{}}, :sync)
{:ok, "Pong! 🏓"}
iex> PingPong.Notification.send_notification([:mock], :sync)
{:error, {:missing, :payload}}
"""
@spec send_notification(PingPong.config(), PingPong.send_type()) :: PingPong.result()
def send_notification(notification, send_type) do
sender = get_sender(send_type)
case notification do
{service, payload, options}
when is_atom(service) and is_map(payload) and is_map(options) ->
sender.(service, payload, options)
[_] ->
{:error, {:missing, :payload}}
_ ->
{:error, {:invalid, :notification}}
end
end
defp get_sender(:sync), do: &PingPong.send/3
defp get_sender(:async), do: &PingPong.send_async/3
end