JSV.Normalizer (jsv v0.7.2)

View Source

A Normalizer for JSON data structures.

Summary

Functions

Default implementation for the :on_general_atom option of normalize/2 and normalize/3. Transforms atoms to strings.

Returns the given term in a JSON-decoded form without general atoms or structs.

Returns the given term in a JSON-decoded form without general atoms or structs. Accepts and returns an accumulator.

Types

json_decoded_form()

@type json_decoded_form() ::
  %{optional(String.t()) => json_decoded_form()}
  | [json_decoded_form()]
  | String.t()
  | number()
  | true
  | false
  | nil

Functions

default_on_general_atom(atom, acc)

@spec default_on_general_atom(atom(), term()) :: {String.t(), term()}

Default implementation for the :on_general_atom option of normalize/2 and normalize/3. Transforms atoms to strings.

normalize(term, opts \\ [])

@spec normalize(
  term(),
  keyword()
) :: json_decoded_form()

Returns the given term in a JSON-decoded form without general atoms or structs.

See normalize/3 for details and options.

Examples

iex> JSV.Normalizer.normalize(%{name: :joe})
%{"name" => "joe"}

iex> JSV.Normalizer.normalize(%{"name" => :joe})
%{"name" => "joe"}

iex> JSV.Normalizer.normalize(%{"name" => "joe"})
%{"name" => "joe"}

iex> JSV.Normalizer.normalize(%{true: false})
%{"true" => false}

iex> JSV.Normalizer.normalize(%{specials: [true, false, nil]})
%{"specials" => [true, false, nil]}

This function is also used internally to normalize schemas.

iex> JSV.Normalizer.normalize(%JSV.Schema{title: nil, properties: nil})
%{}

iex> JSV.Normalizer.normalize(%JSV.Schema{type: :integer})
%{"type" => "integer"}

iex> JSV.Normalizer.normalize(%JSV.Schema{title: :"My Schema"})
%{"title" => "My Schema"}

Other structs must implement the JSV.Normalizer.Normalize protocol.

iex> defimpl JSV.Normalizer.Normalize, for: Range do
iex>   def normalize(range), do: Map.from_struct(range)
iex> end
iex> JSV.Normalizer.normalize(1..10)
%{"first" => 1, "last" => 10, "step" => 1}

normalize(term, opts, acc_in)

@spec normalize(term(), keyword(), term()) :: {json_decoded_form(), term()}

Returns the given term in a JSON-decoded form without general atoms or structs. Accepts and returns an accumulator.

What is JSON-decoded form?

By that we mean that the returned data could have been returned by JSON.decode!/1:

  • Only maps, lists, strings, numbers and atoms.
  • Structs must implement the JSV.Normalizer.Normalize protocol.
  • true, false and nil will be kept as-is in all places except for map keys.
  • true, false and nil as map keys will be converted to string.
  • Other atoms as values will be passed to the :on_general_atom callback (see options).
  • Map keys must only be atoms, strings or numbers and will be converted to strings.

Options

  • :on_general_atom - A callback accepting an atom found in the data and the accumulator. Must return a JSON-compatible

Examples

iex> on_general_atom = fn atom, acc ->
...>   {"found:#{atom}", [atom|acc]}
...> end
iex> opts = [on_general_atom: on_general_atom]
iex> acc_in = []
iex> JSV.Normalizer.normalize(%{an_atom: SomeAtom, a_string: "hello"}, opts, acc_in)
{%{"an_atom" => "found:Elixir.SomeAtom", "a_string" => "hello"}, [SomeAtom]}