lib/customers/customer.ex

defmodule Customers.Customer do
  alias Customers.Phone

  import Utilities, only: [atomize_keys: 1]

  @derive Jason.Encoder

  @type t() :: %__MODULE__{
          id: String.t(),
          email: String.t(),
          default: true | false,
          name: String.t(),
          phone: Phone.t(),
          metadata: map(),
          instruments: list()
        }

  defstruct [
    :id,
    :email,
    :default,
    :name,
    :phone,
    :metadata,
    :instruments
  ]

  def build(raw_params) when is_map(raw_params) do
    params = atomize_keys(raw_params)

    %__MODULE__{
      id: params[:id],
      email: params[:email],
      default: params[:default],
      name: params[:name],
      phone: Phone.build(params[:phone]),
      metadata: atomize_keys(params[:metadata]),
      instruments: build_instruments(params[:instruments])
    }
  end

  def build(_), do: nil

  defp build_instruments(instruments) when is_list(instruments) do
    Enum.into(instruments, [], &Instruments.build(&1))
  end

  defp build_instruments(_), do: []
end