lib/frugality/encoder/md5.ex

defmodule Frugality.Encoder.MD5 do
  @moduledoc """
  Implements the `Frugality.Encoder` behaviour in order to provide an MD5
  `iodata` encoder.
  """

  @behaviour Frugality.Encoder

  @algo :md5

  @impl true
  def encode(payload) when is_binary(payload) do
    :crypto.hash(@algo, payload)
  end

  def encode(payload) when is_list(payload) do
    payload
    |> Enum.reduce(:crypto.hash_init(@algo), &update_hash/2)
    |> :crypto.hash_final()
    |> Base.encode16(case: :lower)
  end

  defp update_hash("", hash), do: hash

  defp update_hash(fragment, hash),
    do: :crypto.hash_update(hash, fragment)
end