Skip to content

Commit 629a179

Browse files
committed
Merge pull request #1 from ruby2elixir/feature/structs
Support for structs + tuples
2 parents 7a1d25a + 42a3722 commit 629a179

3 files changed

Lines changed: 36 additions & 5 deletions

File tree

lib/atomic_map.ex

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11
defmodule AtomicMap do
22
def convert(v, opts \\ [])
3+
4+
def convert(struct=%{__struct__: type}, opts) do
5+
struct
6+
|> Map.from_struct
7+
|> convert(opts)
8+
|> Map.put(:__struct__, type)
9+
end
10+
311
def convert(map, opts) when is_map(map) do
412
safe = Keyword.get(opts, :safe, true)
513
map |> Enum.reduce(%{}, fn({k,v}, acc)->
6-
if is_binary(k), do: k = as_atom(k, safe)
7-
if is_complex?(v), do: v = convert(v, opts)
14+
k = as_atom(k, safe)
15+
v = convert(v, opts)
816
acc |> Map.put(k, v)
917
end)
1018
end
1119
def convert(list, opts) when is_list(list) do
1220
list |> Enum.map(fn(x)-> convert(x, opts) end)
1321
end
22+
def convert(tuple, opts) when is_tuple(tuple) do
23+
tuple |> Tuple.to_list |> convert(opts) |> List.to_tuple
24+
end
1425
def convert(v, _opts), do: v
15-
16-
defp is_complex?(v), do: is_map(v) || is_list(v)
1726
defp as_atom(s, true) when is_binary(s), do: s |> String.to_existing_atom
1827
defp as_atom(s, true), do: s
1928

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule AtomicMap.Mixfile do
22
use Mix.Project
33

4-
@version "0.6.0"
4+
@version "0.7.0"
55
def project do
66
[app: :atomic_map,
77
version: @version,

test/atomic_map_test.exs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ defmodule AtomicMapTest do
22
use ExUnit.Case
33
doctest AtomicMap
44

5+
defmodule MyStruct do
6+
defstruct first: nil, second: nil
7+
end
8+
59
test "works with maps" do
610
input = %{"a" => 2, "b" => %{"c" => 4}}
711
expected = %{a: 2, b: %{c: 4}}
@@ -38,6 +42,24 @@ defmodule AtomicMapTest do
3842
assert AtomicMap.convert(input) == expected
3943
end
4044

45+
test "works with structs" do
46+
input = %AtomicMapTest.MyStruct{first: [%{"a" => 1}]}
47+
expected = %AtomicMapTest.MyStruct{first: [%{a: 1}]}
48+
assert AtomicMap.convert(input) == expected
49+
end
50+
51+
test "works with nested structs" do
52+
input = %AtomicMapTest.MyStruct{first: [%AtomicMapTest.MyStruct{first: %{"b" => 1}}]}
53+
expected = %AtomicMapTest.MyStruct{first: [%AtomicMapTest.MyStruct{first: %{b: 1}}]}
54+
assert AtomicMap.convert(input) == expected
55+
end
56+
57+
test "works with tuples" do
58+
input = %{ "first" => {1,2}}
59+
expected = %{first: {1, 2}}
60+
assert AtomicMap.convert(input) == expected
61+
end
62+
4163
test "raises for not existing atoms" do
4264
assert_raise ArgumentError, fn ->
4365
input = %{"a" => 2, "b" => %{"c" => 4}, "__not___existing__" => 5}

0 commit comments

Comments
 (0)