Skip to content

Commit 3b7bfc3

Browse files
committed
improve to also handle lists + simpler code
1 parent 061e841 commit 3b7bfc3

2 files changed

Lines changed: 36 additions & 10 deletions

File tree

lib/atomic_map.ex

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
defmodule AtomicMap do
2+
23
def convert(map, opts) when is_map(map) do
34
safe = Keyword.get(opts, :safe, true)
4-
map |> Enum.reduce(%{}, fn
5-
# convert strings to atoms
6-
{k,v}, acc when is_binary(k) and is_map(v)
7-
-> Map.put(acc, as_atom(k, safe), convert(v, opts));
8-
{k,v}, acc when is_map(v)
9-
-> Map.put(acc, k, convert(v, opts));
10-
{k,v}, acc when is_binary(k)
11-
-> Map.put(acc, as_atom(k, safe), v);
12-
{k,v}, acc
13-
-> Map.put(acc, k, v)
5+
map |> Enum.reduce(%{}, fn({k,v}, acc)->
6+
if is_binary(k), do: k = as_atom(k, safe)
7+
cond do
8+
is_complex?(v) -> Map.put(acc, k, convert(v, opts));
9+
true -> Map.put(acc, k, v)
10+
end
1411
end)
1512
end
13+
def convert(list, opts) when is_list(list) do
14+
list |> Enum.map(fn(x)-> convert(x, opts) end)
15+
end
16+
def convert(v, opts), do: v
1617

18+
defp is_complex?(v), do: is_map(v) || is_list(v)
1719
defp as_atom(s, true) when is_binary(s), do: s |> String.to_existing_atom
1820
defp as_atom(s, true), do: s
1921

test/atomic_map_test.exs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,30 @@ defmodule AtomicMapTest do
88
assert AtomicMap.convert(input, safe: true) == expected
99
end
1010

11+
test "works with maps with lists" do
12+
input = %{ "a" => [ %{"c" => 1}, %{"c" => 2}] }
13+
expected = %{a: [%{c: 1}, %{c: 2}] }
14+
assert AtomicMap.convert(input, safe: true) == expected
15+
end
16+
17+
test "works with lists with maps" do
18+
input = [ %{"c" => 1}, %{"c" => 2}, %{"c" => %{"b" => 4}}]
19+
expected = [%{c: 1}, %{c: 2}, %{c: %{b: 4}}]
20+
assert AtomicMap.convert(input, safe: true) == expected
21+
end
22+
23+
test "works with mixed keys (string / atoms)" do
24+
input = [ %{"c" => 1}, %{:c => 2}, %{"c" => %{:b => 4}}]
25+
expected = [%{c: 1}, %{c: 2}, %{c: %{b: 4}}]
26+
assert AtomicMap.convert(input, safe: true) == expected
27+
end
28+
29+
test "works with simple values" do
30+
input = "2"
31+
expected = "2"
32+
assert AtomicMap.convert(input, safe: true) == expected
33+
end
34+
1135
test "raises for not existing atoms" do
1236
assert_raise ArgumentError, fn ->
1337
input = %{"a" => 2, "b" => %{"c" => 4}, "__not___existing__" => 5}

0 commit comments

Comments
 (0)