Skip to content

Commit

Permalink
Merge pull request #207 from rauann/rauann/as-function
Browse files Browse the repository at this point in the history
  • Loading branch information
devinus authored May 31, 2024
2 parents af4ae70 + 09d9a53 commit 6fc4b7a
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
6 changes: 5 additions & 1 deletion lib/poison/decoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ defmodule Poison.Decode do
for v <- value, do: transform(v, keys, as, options)
end

defp transform(value, keys, as, options) when is_function(as, 1) do
transform(value, keys, as.(value), options)
end

defp transform(value, _keys, _as, _options) do
value
end
Expand Down Expand Up @@ -106,7 +110,7 @@ end
defprotocol Poison.Decoder do
@fallback_to_any true

@typep as :: map | struct | [as]
@typep as :: map | struct | [as] | (t -> as | [as])

@typep option :: {:keys, :atoms | :atoms!} | {:decimal, boolean} | {:as, as}
@type options ::
Expand Down
36 changes: 36 additions & 0 deletions test/poison/decoder_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,40 @@ defmodule Poison.DecoderTest do
assert transform(address, %{as: %Address{}}) ==
"1 Main St., Austin, TX 78701"
end

test "decoding a sigle :as function with string keys" do
person = %{"name" => "Devin Torres"}
as = fn %{"name" => _name} -> %Person{} end
expected = %Person{name: "Devin Torres"}
assert transform(person, %{as: as}) == expected
end

test "decoding a single :as function with atom keys" do
person = %{name: "Devin Torres"}
as = fn %{name: _name} -> %Person{} end
expected = %Person{name: "Devin Torres"}
assert transform(person, %{as: as, keys: :atoms!}) == expected
end

test "decoding a :as list function with string keys" do
person = [%{"name" => "Devin Torres"}]
as = fn _value -> [%Person{}] end
expected = [%Person{name: "Devin Torres"}]
assert transform(person, %{as: as}) == expected
end

test "decoding nested :as function with string keys" do
person = %{"person" => %{"name" => "Devin Torres"}}
as = fn _value -> %{"person" => %Person{}} end
actual = transform(person, %{as: as})
expected = %{"person" => %Person{name: "Devin Torres"}}
assert actual == expected
end

test "decoding nested structs in :as function with string keys" do
person = %{"name" => "Devin Torres", "contact" => %{"email" => "[email protected]"}}
as = fn _value -> %Person{contact: %Contact{}} end
expected = %Person{name: "Devin Torres", contact: %Contact{email: "[email protected]"}}
assert transform(person, %{as: as}) == expected
end
end

0 comments on commit 6fc4b7a

Please sign in to comment.