Carry is a super simple, dependency free package that transforms a map from this form:
%{"carillon"=>"sound","marimba"=>"percussion"}to the corresponding Elixir struct.
For example, given this struct:
defmoduleInstrumentdodefstruct[:carillon]endby invoking the function with the expanded struct:
iex>Carry.on(%{"carillon"=>"sound","marimba"=>"percussion"},%Instrument{})%Instrument{carillon: "sound"}or with the atom representing the struct
iex>Carry.on(%{"carillon"=>"sound","marimba"=>"percussion"},Instrument)%Instrument{carillon: "sound"}or as a syntactic sugar functionality
iex>Carry.on(%Instrument{carillon: "sound"},Instrument)%Instrument{carillon: "sound"}which will just call struct(module, Map.from_struct(struct)) under the hood
This is usually useful when having a decoded payload from json (a map) and
we want to convert to an Elixir struct.
This implementation does not use String.to_atom/1 in order to not exhaust the
BEAM atom table limits, since atoms are not garbage collected.
I was using exconstrutor, however I noticed that it seems to generate new
atoms in some corner cases.
See appcues/exconstructor#25 to get more context.
Thanks to to the https://hex.pm/packages/poison library for heavy influence =)
If you are using Poison, you can just do Poison.decode(json_string, as: %YourStruct{})
If available in Hex, the package can be installed
by adding carry to your list of dependencies in mix.exs:
defdepsdo[{:carry,"~> 0.1"}]endDocumentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/carry.