From 06fa2b96d8f0627aff88f6df55d669d6e82eb08f Mon Sep 17 00:00:00 2001 From: Joe Frangoudes Date: Sat, 10 Nov 2018 15:16:32 +0000 Subject: [PATCH] Eljiffy is a compatible json_decoder for Plug.Parsers.JSON --- README.md | 2 ++ lib/eljiffy.ex | 52 ++++++++++++++++++++++++++++++++++++++------------ mix.exs | 2 +- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 8e5affc..eea65c0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Eljiffy +Compatible ```json_decoder``` for ```Plug.Parsers.JSON``` since v1.1.0 + Eljiffy (Elixir Jiffy) is an Elixir wrapper around the erlang JSON nif library Jiffy. It also provides functions to convert json to maps directly rather than having to pass the option return_maps explicitly (https://github.com/davisp/jiffy) diff --git a/lib/eljiffy.ex b/lib/eljiffy.ex index 24aea05..99f5c14 100644 --- a/lib/eljiffy.ex +++ b/lib/eljiffy.ex @@ -4,19 +4,19 @@ defmodule Eljiffy do Eljiffy (Elixir Jiffy) is an Elixir wrapper around the erlang JSON nif library Jiffy. It also provides functions to convert json to maps directly rather than having to pass the option return_maps explicitly - (https://github.com/davisp/jiffy) + (https://github.com/davisp/jiffy) (decode!/1 and decode!/2) - ### The opts parameter for `decode/2` is a list of terms: + ### The opts parameter for `decode_proplist/2` is a list of terms: - `:return_maps` - Tell Jiffy to return objects using the maps data type on VMs that support it. This raises an error on VMs that don't support maps. - `null_term:` term - Returns the specified Term instead of null when decoding JSON. This is for people that wish to use undefined instead of null. - `:use_nil` - Returns the atom nil instead of null when decoding JSON. This is a short hand for `{:null_term, nil}`. - - `:return_trailer` - If any non-whitespace is found after the first JSON term is decoded the return value of `decode/2` becomes `{:has_trailer, firstTerm, restData}`. This is useful to decode multiple terms in a single binary. + - `:return_trailer` - If any non-whitespace is found after the first JSON term is decoded the return value of `decode_proplist/2` becomes `{:has_trailer, firstTerm, restData}`. This is useful to decode multiple terms in a single binary. - `:dedupe_keys` - If a key is repeated in a JSON object this flag will ensure that the parsed object only contains a single entry containing the last value seen. This mirrors the parsing beahvior of virtually every other JSON parser. - `:copy_strings` - Normaly when strings are decoded they are created as sub-binaries of the input data. With some workloads this can lead to an undeseriable bloating of memory when a few small strings in JSON keep a reference to the full JSON document alive. Setting this option will instead allocate new binaries for each string to avoid keeping the original JSON document around after garbage collection. - `bytes_per_red: n where n >= 0` - This controls the number of bytes that Jiffy will process as an equivalent to a reduction. Each 20 reductions we consume 1% of our allocated time slice for the current process. When the Erlang VM indicates we need to return from the NIF. - `bytes_per_iter: n where n >= 0` - Backwards compatible option that is converted into the `bytes_per_red` value. - ### The opts parameter for `encode/2` is a list of terms: + ### The opts parameter for `encode!/2` is a list of terms: - `:uescape` - Escapes UTF-8 sequences to produce a 7-bit clean output - `:pretty` - Produce JSON using two-space indentation - `:force_utf8` - Force strings to encode as UTF-8 by fixing broken surrogate pairs and/or using the replacement character to remove broken UTF-8 sequences in data. @@ -31,7 +31,7 @@ defmodule Eljiffy do ## Examples iex> jsonData = "{\"people\": [{\"name\": \"Joe\"}, {\"name\": \"Robert\"}, {\"name\": \"Mike\"}]}" - iex> Eljiffy.decode(jsonData) + iex> Eljiffy.decode_proplist (jsonData) {[ {"people" [ {[{"name", "Joe"}]}, @@ -40,14 +40,14 @@ defmodule Eljiffy do ]} ]} """ - def decode(data) do + def decode_proplist(data) do :jiffy.decode(data) end @doc """ - Does the same thing as `decode/1`, but accepts decode options (see [opts](#module-the-opts-parameter-for-decode-2-is-a-list-of-terms)) + Does the same thing as `decode_proplist/1`, but accepts decode options (see [opts](#module-the-opts-parameter-for-decode-2-is-a-list-of-terms)) """ - def decode(data, opts) do + def decode_proplist(data, opts) do :jiffy.decode(data, opts) end @@ -56,17 +56,17 @@ defmodule Eljiffy do ## Examples iex> term = %{:langs => [%{:elixir => %{:beam => :true}}, %{:erlang => %{:beam => :true}}, %{:rust => %{:beam => :false}}]} - iex> Eljiffy.encode(term) + iex> Eljiffy.encode!(term) "{\"langs\":[{\"elixir\":{\"beam\":true}},{\"erlang\":{\"beam\":true}},{\"rust\":{\"beam\":false}}]}" """ - def encode(data) do + def encode!(data) do :jiffy.encode(data) end @doc """ - Does the same thing as `encode/1` but accepts encode options (see [opts](#module-the-opts-parameter-for-encode-2-is-a-list-of-terms)) + Does the same thing as `encode!/1` but accepts encode options (see [opts](#module-the-opts-parameter-for-encode-2-is-a-list-of-terms)) """ - def encode(data, opts) do + def encode!(data, opts) do :jiffy.encode(data, opts) end @@ -83,6 +83,8 @@ defmodule Eljiffy do ]} """ + @since "1.1.0" + @deprecated "use decode!/1 instead" def decode_maps(data) do :jiffy.decode(data, [:return_maps]) end @@ -90,7 +92,33 @@ defmodule Eljiffy do @doc """ Does the same thing as `decode_maps/1` but accepts decode options (see [opts](#module-the-opts-parameter-for-decode-2-is-a-list-of-terms)) """ + @since "1.1.0" + @deprecated "use decode!/2 instead" def decode_maps(data, opts) do :jiffy.decode(data, [:return_maps] ++ opts) end + + @doc """ + Transforms a json string into a map + ## Examples + + iex> jsonData = "{\"people\": [{\"name\": \"Joe\"}, {\"name\": \"Robert\"}, {\"name\": \"Mike\"}]}" + iex> Eljiffy.decode!(jsonData) + %{:people => [ + %{:name => "Joe"}, + %{:name => "Robert"}, + %{:name => "Mike"} + ]} + + """ + def decode!(data) do + :jiffy.decode(data, [:return_maps]) + end + + @doc """ + Does the same thing as `decode!/1` but accepts decode options (see [opts](#module-the-opts-parameter-for-decode-2-is-a-list-of-terms)) + """ + def decode!(data, opts) do + :jiffy.decode(data, [:return_maps] ++ opts) + end end diff --git a/mix.exs b/mix.exs index 7e8bd30..8d10a56 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule Eljiffy.MixProject do [ app: :eljiffy, description: "An Elixir wrapper around the erlang json nifs library, Jiffy (github.com/davisp/jiffy)", - version: "1.0.0", + version: "1.1.0", elixir: "~> 1.6", start_permanent: Mix.env() == :prod, deps: deps(),