defmodule Timex.Format.Duration.Formatter do @moduledoc """ This module defines the behaviour for custom Time formatters """ use Timex alias Timex.Translator alias Timex.Duration alias Timex.Format.Duration.Formatters.Default alias Timex.Format.Duration.Formatters.Humanized defmacro __using__(_) do quote do alias Timex.Duration @behaviour Timex.Format.Duration.Formatter end end @callback format(Duration.t()) :: String.t() | {:error, term} @callback lformat(Duration.t(), locale :: String.t()) :: String.t() | {:error, term} @doc """ Formats a Duration as a string, using the provided formatter. If a formatter is not provided, the formatter used is `Timex.Format.Duration.Formatters.Default`. As a handy shortcut, you can reference the other built-in formatter (Humanized) via the :humanized atom as shown below. # Examples iex> d = Timex.Duration.from_erl({1435, 180354, 590264}) ...> #{__MODULE__}.format(d) "P45Y6M5DT21H12M34.590264S" """ @spec format(Duration.t()) :: String.t() | {:error, term} def format(duration), do: lformat(duration, Translator.current_locale(), Default) @doc """ Same as format/1, but takes a formatter name as an argument ## Examples iex> d = Timex.Duration.from_erl({1435, 180354, 590264}) ...> #{__MODULE__}.format(d, :humanized) "45 years, 6 months, 5 days, 21 hours, 12 minutes, 34 seconds, 590.264 milliseconds" """ @spec format(Duration.t(), atom) :: String.t() | {:error, term} def format(duration, formatter), do: lformat(duration, Translator.current_locale(), formatter) @doc """ Same as format/1, but takes a locale name as an argument, and translates the format string, if the locale has translations. """ @spec lformat(Duration.t(), String.t()) :: String.t() | {:error, term} def lformat(duration, locale), do: lformat(duration, locale, Default) @doc """ Same as lformat/2, but takes a formatter as an argument """ @spec lformat(Duration.t(), String.t(), atom) :: String.t() | {:error, term} def lformat(%Duration{} = duration, locale, formatter) when is_binary(locale) and is_atom(formatter) do case formatter do :humanized -> Humanized.lformat(duration, locale) _ -> formatter.lformat(duration, locale) end end def lformat(_, _, _), do: {:error, :invalid_duration} end