Converting a nested map with string keys into a struct with nested atom keys

816 views
Skip to first unread message

Aaron Jensen

unread,
Apr 11, 2016, 2:07:15 PM4/11/16
to elixir-lang-talk
Hi there,

We have a struct similar to:

defmodule MyStruct do
  @type t :: %__MODULE__{
    field: integer,
    nested_map: %{
      nested_field: integer,
    },
  }

  defstruct [
    :field,
    :nested_map,
  ]
end

And we would like to be able to safely (without String.to_atom) convert user input like:

%{"field" => 3, "nested_map" => %{"nested_field" => 4}}

to a struct, like:

%MyStruct{field: 3, nested_map: %{nested_field: 4}}



I haven't been able to find an obvious way of doing this that doesn't incur significant duplication or work. We have tried recursively using `String.to_existing_atom/1`, but :nested_field won't be in the atom table unless some code that uses it has been loaded somewhere, which isn't always the case for us.

I've been able to ensure that the atoms are in the atom table by doing `Kernel.Typespec.beam_types(MyStruct)` but that seems like a huge hack.

Is there an idiomatic way of doing this? Or am I looking at a macro that defines the typespec, the struct and the Poison.Decoder implementation all at once?

Thanks,

Aaron

Eric Meadows-Jönsson

unread,
Apr 11, 2016, 2:40:28 PM4/11/16
to elixir-l...@googlegroups.com
I don't think the idiomatic way is using typespecs. They were not made to part of your application logic, they should only be used to annotate your code.

Your idea of building a macro that defines the typespec, struct and json decoder sounds like the best solution.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/3d9d6276-3d49-46a7-8aa9-93e2dbd313c5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Eric Meadows-Jönsson
Reply all
Reply to author
Forward
0 new messages