From 9031b1e42bea82c10e081646f18369c8dca6434a Mon Sep 17 00:00:00 2001 From: Zoey de Souza Pessanha Date: Sat, 6 Jul 2024 20:10:05 -0300 Subject: [PATCH] feaT: basic jason protocol support --- lib/peri/error.ex | 53 ++++++++++++++++++++++++++++++++++++++++++++++- mix.exs | 1 + 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/lib/peri/error.ex b/lib/peri/error.ex index 796bde6..bae3281 100644 --- a/lib/peri/error.ex +++ b/lib/peri/error.ex @@ -198,15 +198,66 @@ defmodule Peri.Error do %{ path: err.path, key: err.key, - content: err.content, + content: transform_content(err.content), message: err.message, errors: transform_errors(err.errors) } end + defp transform_content(content) do + for {k, v} <- content do + if is_tuple(v) do + {k, transform_tuple(v)} + else + {k, v} + end + end + |> Map.new() + end + + defp transform_tuple(tuple) when is_tuple(tuple) do + for el <- Tuple.to_list(tuple) do + if is_tuple(el) do + transform_tuple(el) + else + el + end + end + end + defp transform_errors(nil), do: nil defp transform_errors(errors) when is_list(errors) do Enum.map(errors, &error_to_map/1) end + + if Code.ensure_loaded?(:json) do + def error_to_json(%Peri.Error{} = err) do + err + |> Peri.Error.error_to_map() + |> transform_nil() + |> :json.encode() + end + + defp transform_nil(err) do + for {k, v} <- err do + cond do + is_nil(v) -> {k, :null} + is_map(v) -> {k, transform_nil(v)} + true -> {k, v} + end + end + |> Map.new() + end + end + + if Code.ensure_loaded?(Jason) do + defimpl Jason.Encoder, for: __MODULE__ do + def encode(%Peri.Error{} = err, opts) do + err + |> Peri.Error.error_to_map() + |> Jason.Encode.map(opts) + end + end + end end diff --git a/mix.exs b/mix.exs index 1fd72ba..7a299e7 100644 --- a/mix.exs +++ b/mix.exs @@ -26,6 +26,7 @@ defmodule Peri.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ + {:jason, "~> 1.0", optional: true}, {:stream_data, "~> 1.1", optional: true}, {:credo, "~> 1.7", only: :dev, runtime: false}, {:ex_doc, "~> 0.14", only: :dev, runtime: false}