0

The 1.0 implementation looks like this.

defmodule Chat do
  use GenServer

  @derive [Access, Collectable]
  defstruct [api: APIClient, chat_id: nil, clients: %{}]

  def start_link(params), do: GenServer.start_link(__MODULE__, params)

  def init(params) do
    state = Enum.into(params, %__MODULE__{})
    {:ok, state}
  end

  ...
end

First problem is that Access has been deprecated, does that mean I have to change the dot notation when accessing state fields?

Second problem is that if I don't remove the @derive Collectable I get this error Collectable.Any is not available, cannot derive Collectable .... Here params is a keyword list, I supose I could convert the keyword list to a Map with state = Map.merge(%__MODULE__{}, Enum.into(params, %{})) but feels terribly clumsy.

Macario
  • 2,214
  • 2
  • 22
  • 40

1 Answers1

1

I'm not sure about the particular Collectable issue, but there's a much better solution to your particular problem - constructing a struct from a list of key-value pairs. You can use Kernel.struct/2 for that. It won't only construct the struct for you, but also validate the keys, and use only those that really are in the struct. Since 1.2 there's Kernel.struct!/2 that will raise in case any of the provided keys is invalid.

michalmuskala
  • 11,028
  • 2
  • 36
  • 47