Skip to content

Commit 6fc4b7a

Browse files
authored
Merge pull request #207 from rauann/rauann/as-function
2 parents af4ae70 + 09d9a53 commit 6fc4b7a

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

lib/poison/decoder.ex

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ defmodule Poison.Decode do
4242
for v <- value, do: transform(v, keys, as, options)
4343
end
4444

45+
defp transform(value, keys, as, options) when is_function(as, 1) do
46+
transform(value, keys, as.(value), options)
47+
end
48+
4549
defp transform(value, _keys, _as, _options) do
4650
value
4751
end
@@ -106,7 +110,7 @@ end
106110
defprotocol Poison.Decoder do
107111
@fallback_to_any true
108112

109-
@typep as :: map | struct | [as]
113+
@typep as :: map | struct | [as] | (t -> as | [as])
110114

111115
@typep option :: {:keys, :atoms | :atoms!} | {:decimal, boolean} | {:as, as}
112116
@type options ::

test/poison/decoder_test.exs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,4 +197,40 @@ defmodule Poison.DecoderTest do
197197
assert transform(address, %{as: %Address{}}) ==
198198
"1 Main St., Austin, TX 78701"
199199
end
200+
201+
test "decoding a sigle :as function with string keys" do
202+
person = %{"name" => "Devin Torres"}
203+
as = fn %{"name" => _name} -> %Person{} end
204+
expected = %Person{name: "Devin Torres"}
205+
assert transform(person, %{as: as}) == expected
206+
end
207+
208+
test "decoding a single :as function with atom keys" do
209+
person = %{name: "Devin Torres"}
210+
as = fn %{name: _name} -> %Person{} end
211+
expected = %Person{name: "Devin Torres"}
212+
assert transform(person, %{as: as, keys: :atoms!}) == expected
213+
end
214+
215+
test "decoding a :as list function with string keys" do
216+
person = [%{"name" => "Devin Torres"}]
217+
as = fn _value -> [%Person{}] end
218+
expected = [%Person{name: "Devin Torres"}]
219+
assert transform(person, %{as: as}) == expected
220+
end
221+
222+
test "decoding nested :as function with string keys" do
223+
person = %{"person" => %{"name" => "Devin Torres"}}
224+
as = fn _value -> %{"person" => %Person{}} end
225+
actual = transform(person, %{as: as})
226+
expected = %{"person" => %Person{name: "Devin Torres"}}
227+
assert actual == expected
228+
end
229+
230+
test "decoding nested structs in :as function with string keys" do
231+
person = %{"name" => "Devin Torres", "contact" => %{"email" => "[email protected]"}}
232+
as = fn _value -> %Person{contact: %Contact{}} end
233+
expected = %Person{name: "Devin Torres", contact: %Contact{email: "[email protected]"}}
234+
assert transform(person, %{as: as}) == expected
235+
end
200236
end

0 commit comments

Comments
 (0)