Skip to content

Instantly share code, notes, and snippets.

@greenboxal
Created August 31, 2017 04:53
Show Gist options
  • Save greenboxal/7894dbf842175ed82be13856bbef959b to your computer and use it in GitHub Desktop.
Save greenboxal/7894dbf842175ed82be13856bbef959b to your computer and use it in GitHub Desktop.
@control_keys ["$type"]
def cast_args(args) when is_map(args) do
{control, args} = Map.split(args, @control_keys)
type = Map.get(control, "$type", "map")
cast_arg(type, args, control)
end
def cast_args(args) when is_list(args), do: Enum.map(args, &cast_args/1)
def cast_args(arg), do: arg
defp cast_arg("$map", args, control) do
args
|> Enum.map(fn {k, v} ->
{cast_key(k, control), cast_args(v)}
end)
|> Map.new
end
defp cast_arg("$list", args, control) do
args
|> Enum.map(fn {k, v} ->
{cast_key(k, control), cast_args(v)}
end)
end
defp cast_arg("$tuple", args, _control) do
List.to_tuple(args["tuple"])
end
defp cast_arg(type, args, _control) do
args =
args
|> Enum.map(fn {k, v} ->
{String.to_existing_atom(k), v}
end)
Kernel.struct!(cast_type(type), args)
end
def cast_key(key, _control) do
case key do
":" <> key ->
String.to_existing_atom(key)
key ->
key
end
end
def cast_type(type) do
type
|> String.split(".")
|> Enum.reduce(fn (name, acc) -> Module.concat(acc, name) end)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment