Skip to content

Commit e79fcc4

Browse files
committed
Revert to allow any term in encodable type.
* Moved the plain JSON types to the top. * Added type `str` to have a complete set of plain JSON types. * Refer to options either as encoder or decoder options. * Renamed some types to include a clarifying enc_/dec_ prefix.
1 parent e790b50 commit e79fcc4

File tree

1 file changed

+36
-25
lines changed

1 file changed

+36
-25
lines changed

lib/jason.ex

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,47 @@ defmodule Jason do
55

66
alias Jason.{Encode, Decoder, DecodeError, EncodeError, Formatter}
77

8-
@typedoc "Encoding setting for string escapes."
9-
@type escape :: :json | :unicode_safe | :html_safe | :javascript_safe
10-
@typedoc "Encoding setting for maps."
11-
@type maps :: :naive | :strict
12-
@typedoc "Available encoding options."
13-
@type encode_opt :: {:escape, escape} | {:maps, maps} | {:pretty, boolean | Formatter.opts()}
8+
@typedoc "A plain JSON string."
9+
@type str :: String.t()
10+
@typedoc "A plain JSON object where keys can only be strings."
11+
@type object :: %{optional(str) => value}
12+
@typedoc "A plain JSON array with JSON element values."
13+
@type array :: [value]
14+
@typedoc "A plain JSON value. Meaningful for specs where it's certain that nothing else is contained."
15+
@type value :: nil | str | number | boolean | array | object
16+
17+
@typedoc "Encoder setting for string escapes."
18+
@type enc_escape :: :json | :unicode_safe | :html_safe | :javascript_safe
19+
@typedoc "Encoder setting for maps."
20+
@type enc_maps :: :naive | :strict
21+
@typedoc "Available encoder options."
22+
@type encode_opt ::
23+
{:escape, enc_escape} | {:maps, enc_maps} | {:pretty, boolean | Formatter.opts()}
1424

1525
@typedoc "The type of the value returned by the custom decoder function."
16-
@type map_key :: term
26+
@type dec_map_key :: term
1727
@typedoc "Decoding setting for map keys."
18-
@type keys :: :atoms | :atoms! | :strings | :copy | (key :: String.t() -> map_key)
28+
@type dec_keys :: :atoms | :atoms! | :strings | :copy | (key :: str -> dec_map_key)
1929
@typedoc "Decoding setting for strings."
20-
@type strings :: :reference | :copy
30+
@type dec_strings :: :reference | :copy
2131
@typedoc "Decoding setting for floats."
22-
@type floats :: :native | :decimals
32+
@type dec_floats :: :native | :decimals
2333
@typedoc "Decoding setting for objects."
24-
@type objects :: :maps | :ordered_objects
34+
@type dec_objects :: :maps | :ordered_objects
2535
@typedoc "Available decoding options."
26-
@type decode_opt :: {:keys, keys} | {:strings, strings} | {:floats, floats} | {:objects, objects}
36+
@type decode_opt ::
37+
{:keys, dec_keys}
38+
| {:strings, dec_strings}
39+
| {:floats, dec_floats}
40+
| {:objects, dec_objects}
2741

28-
@typedoc "A plain JSON object where keys can only be strings."
29-
@type object :: %{String.t() => value}
30-
@typedoc "A plain JSON array."
31-
@type array :: [value]
32-
@typedoc "A plain JSON value."
33-
@type value :: nil | String.t() | number | boolean | array | object
3442
@typedoc "A decoded JSON value where map keys can have any type."
35-
@type decoded :: [decoded] | %{map_key => decoded} | value
36-
@typedoc "The type of map keys that can be encoded."
37-
@type encodable_key :: String.t() | number | atom | [encodable_key]
38-
@typedoc "The types that can be encoded. Not included are: `tuple`s, `function`s, `reference`s, `port`s and `pid`s."
39-
@type encodable :: String.t() | number | atom | [encodable] | %{encodable_key => encodable}
43+
@type decoded :: value | [decoded] | %{optional(dec_map_key) => decoded}
44+
@typedoc """
45+
The types that can be encoded. In general it will be a JSON `t:value` but
46+
it can be any `term` that has the `c:Jason.Encoder` protocol implemented.
47+
"""
48+
@type encodable :: value | term
4049

4150
@doc """
4251
Parses a JSON value from `input` iodata.
@@ -152,7 +161,7 @@ defmodule Jason do
152161
153162
"""
154163
@spec encode(encodable, [encode_opt]) ::
155-
{:ok, String.t()} | {:error, EncodeError.t() | Exception.t()}
164+
{:ok, str} | {:error, EncodeError.t() | Exception.t()}
156165
def encode(input, opts \\ []) do
157166
case do_encode(input, format_encode_opts(opts)) do
158167
{:ok, result} -> {:ok, IO.iodata_to_binary(result)}
@@ -175,7 +184,7 @@ defmodule Jason do
175184
** (Jason.EncodeError) invalid byte 0xFF in <<255>>
176185
177186
"""
178-
@spec encode!(encodable, [encode_opt]) :: String.t() | no_return
187+
@spec encode!(encodable, [encode_opt]) :: str | no_return
179188
def encode!(input, opts \\ []) do
180189
case do_encode(input, format_encode_opts(opts)) do
181190
{:ok, result} -> IO.iodata_to_binary(result)
@@ -250,10 +259,12 @@ defmodule Jason do
250259
Encode.encode(input, opts)
251260
end
252261

262+
@spec format_encode_opts([encode_opt]) :: %{atom => any}
253263
defp format_encode_opts(opts) do
254264
Enum.into(opts, %{escape: :json, maps: :naive})
255265
end
256266

267+
@spec format_decode_opts([encode_opt]) :: %{atom => any}
257268
defp format_decode_opts(opts) do
258269
Enum.into(opts, %{keys: :strings, strings: :reference, floats: :native, objects: :maps})
259270
end

0 commit comments

Comments
 (0)