From 9f973986b87e554dc87d230a8ce7eb6edb72a88f Mon Sep 17 00:00:00 2001 From: Daniel Azuma Date: Wed, 4 Dec 2019 14:55:17 -0800 Subject: [PATCH] Add support for Poison 4 --- .../gax/lib/google_api/gax/data_wrapper.ex | 2 +- clients/gax/lib/google_api/gax/model_base.ex | 29 +++++++++++++++++-- clients/gax/mix.exs | 4 +-- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/clients/gax/lib/google_api/gax/data_wrapper.ex b/clients/gax/lib/google_api/gax/data_wrapper.ex index 9a0237ab78..ca0d082ac1 100644 --- a/clients/gax/lib/google_api/gax/data_wrapper.ex +++ b/clients/gax/lib/google_api/gax/data_wrapper.ex @@ -45,7 +45,7 @@ defmodule GoogleApi.Gax.DataWrapper do @spec decode(GoogleApi.Gax.DataWrapper.t(), keyword()) :: any() def decode(data_wrapper, options) do struct = options[:struct] - Poison.Decode.decode(data_wrapper.data, as: struct) + GoogleApi.Gax.ModelBase.poison_transform(data_wrapper.data, %{as: struct}) end end diff --git a/clients/gax/lib/google_api/gax/model_base.ex b/clients/gax/lib/google_api/gax/model_base.ex index 07c2f8fa79..910deefa41 100644 --- a/clients/gax/lib/google_api/gax/model_base.ex +++ b/clients/gax/lib/google_api/gax/model_base.ex @@ -13,6 +13,8 @@ # limitations under the License. defmodule GoogleApi.Gax.ModelBase do + require Poison.Decode + @moduledoc """ This module helps you quickly and concisely define API models. @@ -97,17 +99,38 @@ defmodule GoogleApi.Gax.ModelBase do def decode(value, :map, module) when not is_nil(value) do value |> Enum.map(fn {k, v} -> - {k, Poison.Decode.decode(v, as: struct(module))} + {k, poison_transform(v, %{as: struct(module)})} end) |> Enum.into(%{}) end def decode(value, :list, module) do - Poison.Decode.decode(value, as: [struct(module)]) + poison_transform(value, %{as: [struct(module)]}) end def decode(value, _, module) do - Poison.Decode.decode(value, as: struct(module)) + poison_transform(value, %{as: struct(module)}) + end + + if function_exported?(Poison.Decode, :decode, 2) do + def poison_transform(value, options) do + Poison.Decode.decode(value, options) + end + else + # Short-circuit if the value has already been transformed. + # This works around a bug in poison 4 where Poison.decode does an extra + # transformation pass on sub-structs. + def poison_transform(%{__struct__: _} = value, %{as: _}) do + value + end + + def poison_transform([%{__struct__: _} | _] = value, %{as: [_]}) do + value + end + + def poison_transform(value, options) do + Poison.Decode.transform(value, options) + end end @doc """ diff --git a/clients/gax/mix.exs b/clients/gax/mix.exs index f6c89e6b24..e7c76b04cd 100644 --- a/clients/gax/mix.exs +++ b/clients/gax/mix.exs @@ -1,7 +1,7 @@ defmodule GoogleApi.Gax.MixProject do use Mix.Project - @version "0.2.0" + @version "0.3.0" def project do [ @@ -27,7 +27,7 @@ defmodule GoogleApi.Gax.MixProject do defp deps() do [ {:tesla, "~> 1.2"}, - {:poison, ">= 1.0.0 and < 4.0.0"}, + {:poison, ">= 3.0.0 and < 5.0.0"}, {:ex_doc, "~> 0.16", only: :dev}, {:dialyxir, "~> 0.5", only: [:dev], runtime: false} ]