選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

116 行
3.9 KiB

  1. defmodule Jiffy do
  2. @moduledoc """
  3. A JSON parser as a NIF.
  4. # Data Format
  5. | Elixir | -> JSON | -> Elixir |
  6. | ---------------------------- | ---------------- | ------- |
  7. | `nil` | `null` | `nil` |
  8. | `true` | `true` | `true` |
  9. | `false` | `false` | `false` |
  10. | `'hi'` | `[104, 105]` | `[104, 105]` |
  11. | `"hi"` | `"hi"` | `"hi"` |
  12. | `:hi` | `"hi"` | `"hi"` |
  13. | `1` | `1` | `1` |
  14. | `1.25` | `1.25` | `1.25` |
  15. | `[]` | `[]` | `[]` |
  16. | `[true, 1.0]` | `[true, 1.0]` | `[true, 1.0]` |
  17. | `%{"foo" => "bar"}` | `{"foo": "bar"}` | `%{"foo" => "bar"}` |
  18. | `%{foo: "bar"}` | `{"foo": "bar"}` | `%{"foo" => "bar"}` |
  19. """
  20. @encode_options [:use_nil]
  21. @decode_options [:use_nil, :return_maps]
  22. @doc """
  23. Encode a value to JSON.
  24. # Unsupported structures
  25. * Encoding Keywords currently is not supported.
  26. * Encoding DateTime, Date or other Date-related Elixir structures will return
  27. `{:error, {:invalid_ejson, any}}`. If you want to encode them - you need to cast
  28. them to string before encoding.
  29. # Options
  30. * `:uescape` - Escapes UTF-8 sequences to produce a 7-bit clean output.
  31. * `:pretty` - Produce JSON using two-space indentation.
  32. * `:force_utf8` - Force strings to encode as UTF-8 by fixing broken
  33. surrogate pairs and/or using the replacement character to remove
  34. broken UTF-8 sequences in data.
  35. * `:escape_forward_slashes` - Escapes the `/` character which can be
  36. useful when encoding URLs in some cases.
  37. * `{:bytes_per_red, n}` - Refer to the `decode/2` options.
  38. * `{:bytes_per_iter, n}` - Refer to the `decode/2` options.
  39. # Examples
  40. iex> Jiffy.encode([1, 2, 3])
  41. {:ok, "[1,2,3]"}
  42. """
  43. @spec encode(any, opts :: :jiffy.encode_option()) :: {:ok, any()} | {:error, any()}
  44. def encode(data, opts \\ []) do
  45. {:ok, encode!(data, opts)}
  46. catch
  47. {:error, reason} -> {:error, reason}
  48. end
  49. @doc """
  50. Encode a value to JSON, raises an exception on error.
  51. For list of options see `encode/2`.
  52. # Examples
  53. iex> Jiffy.encode!([1, 2, 3])
  54. "[1,2,3]"
  55. """
  56. @spec encode!(any, opts :: :jiffy.encode_option()) :: {:ok, any()} | no_return()
  57. def encode!(data, opts \\ []) do
  58. :jiffy.encode(data, @encode_options ++ opts)
  59. end
  60. @doc """
  61. Decode JSON to a value.
  62. # Options
  63. * `:return_trailer` - If any non-whitespace is found after the first
  64. JSON term is decoded the return value of decode/2 becomes
  65. `{:has_trailer, first_term, rest_iodata}`. This is useful to
  66. decode multiple terms in a single binary.
  67. * `{:bytes_per_red, n}` where `n` >= 0 - This controls the number of
  68. bytes that Jiffy will process as an equivalent to a reduction. Each
  69. 20 reductions we consume 1% of our allocated time slice for the current
  70. process. When the Erlang VM indicates we need to return from the NIF.
  71. * `{:bytes_per_iter, n}` where `n` >= 0 - Backwards compatible option
  72. that is converted into the `bytes_per_red` value.
  73. # Examples
  74. iex> Jiffy.decode("[1,2,3]")
  75. {:ok, [1, 2, 3]}
  76. """
  77. @spec decode(String.t, opts :: :jiffy.decode_option()) :: {:ok, any()} | {:error, atom()}
  78. def decode(data, opts \\ []) do
  79. {:ok, decode!(data, opts)}
  80. catch
  81. {:error, reason} -> {:error, reason}
  82. end
  83. @doc """
  84. Decode JSON to a value, raises an exception on error.
  85. For list of options see `decode/2`.
  86. # Examples
  87. iex> Jiffy.decode!([1, 2, 3])
  88. "[1,2,3]"
  89. """
  90. @spec decode!(String.t, opts :: :jiffy.decode_option()) :: any() | no_return()
  91. def decode!(data, opts \\ []) do
  92. :jiffy.decode(data, @decode_options ++ opts)
  93. end
  94. end