dependabot-hex 0.107.13 → 0.107.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15aedfe164174c16c904b23b71e30a3b273dff70b8713ed84aca18f93a1231d7
4
- data.tar.gz: fd41f3bb22069f06ee8154d8644a0557433edbccb281a3121467d6d2d979c568
3
+ metadata.gz: bdfcd650744ba2ee91ce3df24d3f52491cd67114662992284e4a5a25b225138a
4
+ data.tar.gz: d0fb29f7affd691ca9b4548352b4c760e5656edb42501c6a6d4c0ab126d01705
5
5
  SHA512:
6
- metadata.gz: b8fe78438ccdb4c6e46a854f77d19286895603a2d991bf09627007fbf648734ef3587d1c87ad320901f5e47b0fabba7c2f75c332550d2ffc458c26b54c16a901
7
- data.tar.gz: 0e535724ef7f5fde110c00b0b8498ff418c13645688a8e46e47f371dbd07ad7cc754a4203e4a37241e48f1614f51c65f3fb58b40913eda914bd2721496ed8515
6
+ metadata.gz: 30e28d4e7f5a7567f4e6b5832249ee46980d55d63194e1f222fd58fd7e207b5566874e3f718857c428e2c0e3c74f2bcd266fe1938312f8f5c3d299ff817c64a0
7
+ data.tar.gz: c9750bfdac7b2268a43f1f242da587f3b50240bac1cb54fd230138bd36acc5b6d785bf5b4e2dc22ce61639b8401ab34a5c62dc68c70e987d6cf8a7654e874778
File without changes
@@ -0,0 +1,2 @@
1
+ jason,1.1.2,b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7,hexpm
2
+ mix
@@ -0,0 +1,60 @@
1
+ # Changelog
2
+
3
+ ## 1.1.2 (19.10.2018)
4
+
5
+ ### Bug fixes
6
+
7
+ * correctly handle the `pretty: false` option
8
+ ([ba318c8](https://github.com/michalmuskala/jason/commit/ba318c8)).
9
+
10
+ ## 1.1.1 (10.07.2018)
11
+
12
+ ### Bug fixes
13
+
14
+ * correctly handle escape sequences in strings when pretty printing
15
+ ([794bbe4](https://github.com/michalmuskala/jason/commit/794bbe4)).
16
+
17
+ ## 1.1.0 (02.07.2018)
18
+
19
+ ### Enhancements
20
+
21
+ * pretty-printing support through `Jason.Formatter` and `pretty: true` option
22
+ in `Jason.encode/2` ([d758e36](https://github.com/michalmuskala/jason/commit/d758e36)).
23
+
24
+ ### Bug fixes
25
+
26
+ * silence variable warnings for fields with underscores used during deriving
27
+ ([88dd85c](https://github.com/michalmuskala/jason/commit/88dd85c)).
28
+ * **potential incompatibility** don't raise `Protocol.UndefinedError` in non-bang functions
29
+ ([ad0f57b](https://github.com/michalmuskala/jason/commit/ad0f57b)).
30
+
31
+ ## 1.0.1 (02.07.2018)
32
+
33
+ ### Bug fixes
34
+
35
+ * fix `Jason.Encode.escape` type ([a57b430](https://github.com/michalmuskala/jason/commit/a57b430))
36
+ * multiple documentation improvements
37
+
38
+ ## 1.0.0 (26.01.2018)
39
+
40
+ No changes
41
+
42
+ ## 1.0.0-rc.3 (26.01.2018)
43
+
44
+ ### Changes
45
+
46
+ * update `escape` option of `Jason.encode/2` to take values:
47
+ `:json | :unicode_safe | :html_safe | :javascript_safe` for consistency. Old values of
48
+ `:unicode` and `:javascript` are still supported for compatibility with Poison.
49
+ ([f42dcbd](https://github.com/michalmuskala/jason/commit/f42dcbd))
50
+
51
+ ## 1.0.0-rc.2 (07.01.2018)
52
+
53
+ ### Bug fixes
54
+
55
+ * add type for `strings` option ([b459ee4](https://github.com/michalmuskala/jason/commit/b459ee4))
56
+ * support iodata in `decode!` ([a1f3456](https://github.com/michalmuskala/jason/commit/a1f3456))
57
+
58
+ ## 1.0.0-rc.1 (22.12.2017)
59
+
60
+ Initial release
@@ -0,0 +1,13 @@
1
+ Copyright 2017 Michał Muskała
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,179 @@
1
+ # Jason
2
+
3
+ A blazing fast JSON parser and generator in pure Elixir.
4
+
5
+ The parser and generator are at least twice as fast as other Elixir/Erlang libraries
6
+ (most notably `Poison`).
7
+ The performance is comparable to `jiffy`, which is implemented in C as a NIF.
8
+ Jason is usually only twice as slow.
9
+
10
+ Both parser and generator fully conform to
11
+ [RFC 8259](https://tools.ietf.org/html/rfc8259) and
12
+ [ECMA 404](http://www.ecma-international.org/publications/standards/Ecma-404.htm)
13
+ standards. The parser is tested using [JSONTestSuite](https://github.com/nst/JSONTestSuite).
14
+
15
+ ## Installation
16
+
17
+ The package can be installed by adding `jason` to your list of dependencies
18
+ in `mix.exs`:
19
+
20
+ ```elixir
21
+ def deps do
22
+ [{:jason, "~> 1.1"}]
23
+ end
24
+ ```
25
+
26
+ ## Basic Usage
27
+
28
+ ``` elixir
29
+ iex(1)> Jason.encode!(%{"age" => 44, "name" => "Steve Irwin", "nationality" => "Australian"})
30
+ "{\"age\":44,\"name\":\"Steve Irwin\",\"nationality\":\"Australian\"}"
31
+
32
+ iex(2)> Jason.decode!(~s({"age":44,"name":"Steve Irwin","nationality":"Australian"}))
33
+ %{"age" => 44, "name" => "Steve Irwin", "nationality" => "Australian"}
34
+ ```
35
+
36
+ Full documentation can be found at [https://hexdocs.pm/jason](https://hexdocs.pm/jason).
37
+
38
+ ## Use with other libraries
39
+
40
+ ### Postgrex
41
+
42
+ You need to define a custom "types" module in an `.ex` file, somewhere in `lib`:
43
+
44
+ ```elixir
45
+ Postgrex.Types.define(MyApp.PostgresTypes, [], json: Jason)
46
+
47
+ ## If using with ecto, you also need to pass ecto default extensions:
48
+
49
+ Postgrex.Types.define(MyApp.PostgresTypes, [] ++ Ecto.Adapters.Postgres.extensions(), json: Jason)
50
+ ```
51
+
52
+ Then you can use the module, by passing it to `Postgrex.start_link`.
53
+ ### Ecto
54
+
55
+ To replicate fully the current behaviour of `Poison` when used in Ecto applications,
56
+ you need to configure `Jason` to be the default encoder in `config/config.exs`:
57
+
58
+ ```elixir
59
+ config :ecto, json_library: Jason
60
+ ```
61
+
62
+ Additionally, when using PostgreSQL, you need to define a custom types module as described
63
+ above, and configure your repo to use it (in either `config/config.exs` or `config/<env>.exs`):
64
+
65
+ ```elixir
66
+ config :my_app, MyApp.Repo, types: MyApp.PostgresTypes
67
+ ```
68
+
69
+ ### Plug (and Phoenix)
70
+
71
+ First, you need to configure `Plug.Parsers` to use `Jason` for parsing JSON. You need to find,
72
+ where you're plugging the `Plug.Parsers` plug (in case of Phoenix, it will be in the
73
+ Endpoint module) and configure it in your endpoint module (`lib/app_web/endpoint.ex`),
74
+ for example:
75
+
76
+ ```elixir
77
+ plug Plug.Parsers,
78
+ parsers: [:urlencoded, :multipart, :json],
79
+ pass: ["*/*"],
80
+ json_decoder: Jason
81
+ ```
82
+
83
+ Additionally, for Phoenix, you need to configure the "encoder" in `config/config.exs`:
84
+
85
+ ```elixir
86
+ config :phoenix, :format_encoders,
87
+ json: Jason
88
+ ```
89
+
90
+ A custom JSON encoder for Phoenix channels is unfortunately a bit more involved,
91
+ you can find code for a custom serializer and how to use it [in here](https://gist.github.com/michalmuskala/d5fabcd26be2befdfb72b72e0b0f2797).
92
+
93
+ ### Absinthe
94
+
95
+ You need to pass the `:json_codec` option to `Absinthe.Plug`
96
+
97
+ ```elixir
98
+ # When called directly:
99
+ plug Absinthe.Plug,
100
+ schema: MyApp.Schema,
101
+ json_codec: Jason
102
+
103
+ # When used in phoenix router:
104
+ forward "/api",
105
+ to: Absinthe.Plug,
106
+ init_opts: [schema: MyApp.Schema, json_codec: Jason]
107
+ ```
108
+
109
+ ## Benchmarks
110
+
111
+ Detailed benchmarks (including memory measurements):
112
+ https://gist.github.com/michalmuskala/4d64a5a7696ca84ac7c169a0206640d5
113
+
114
+ HTML reports for the benchmark (only performance measurements):
115
+ http://michal.muskala.eu/jason/decode.html and http://michal.muskala.eu/jason/encode.html
116
+
117
+ ### Running
118
+
119
+ Benchmarks against most popular Elixir & Erlang json libraries can be executed
120
+ with `mix bench.encode` and `mix bench.decode`.
121
+ A HTML report of the benchmarks (after their execution) can be found in
122
+ `bench/output/encode.html` and `bench/output/decode.html` respectively.
123
+
124
+ ## Differences to Poison
125
+
126
+ Jason has a couple feature differences compared to Poison.
127
+
128
+ * Jason follows the JSON spec more strictly, for example it does not allow
129
+ unescaped newline characters in JSON strings - e.g. `"\"\n\""` will
130
+ produce a decoding error.
131
+ * no support for decoding into data structures (the `as:` option).
132
+ * no built-in encoders for `MapSet`, `Range` and `Stream`.
133
+ * no support for encoding arbitrary structs - explicit implementation
134
+ of the `Jason.Encoder` protocol is always required.
135
+ * different pretty-printing customisation options (default `pretty: true` works the same)
136
+
137
+ If you require encoders for any of the unsupported collection types, I suggest
138
+ adding the needed implementations directly to your project:
139
+
140
+ ```elixir
141
+ defimpl Jason.Encoder, for: [MapSet, Range, Stream] do
142
+ def encode(struct, opts) do
143
+ Jason.Encode.list(Enum.to_list(struct), opts)
144
+ end
145
+ end
146
+ ```
147
+
148
+ If you need to encode some struct that does not implement the protocol,
149
+ if you own the struct, you can derive the implementation specifying
150
+ which fields should be encoded to JSON:
151
+
152
+ ```elixir
153
+ @derive {Jason.Encoder, only: [....]}
154
+ defstruct # ...
155
+ ```
156
+
157
+ It is also possible to encode all fields, although this should be
158
+ used carefully to avoid accidentally leaking private information
159
+ when new fields are added:
160
+
161
+ ```elixir
162
+ @derive Jason.Encoder
163
+ defstruct # ...
164
+ ```
165
+
166
+ Finally, if you don't own the struct you want to encode to JSON,
167
+ you may use `Protocol.derive/3` placed outside of any module:
168
+
169
+ ```elixir
170
+ Protocol.derive(Jason.Encoder, NameOfTheStruct, only: [...])
171
+ Protocol.derive(Jason.Encoder, NameOfTheStruct)
172
+ ```
173
+
174
+ ## License
175
+
176
+ Jason is released under the Apache 2.0 License - see the [LICENSE](LICENSE) file.
177
+
178
+ Some elements of tests and benchmarks have their origins in the
179
+ [Poison library](https://github.com/devinus/poison) and were initially licensed under [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).
@@ -0,0 +1,20 @@
1
+ {<<"app">>,<<"jason">>}.
2
+ {<<"build_tools">>,[<<"mix">>]}.
3
+ {<<"description">>,
4
+ <<"A blazing fast JSON parser and generator in pure Elixir.">>}.
5
+ {<<"elixir">>,<<"~> 1.4">>}.
6
+ {<<"files">>,
7
+ [<<"lib">>,<<"lib/codegen.ex">>,<<"lib/decoder.ex">>,<<"lib/encode.ex">>,
8
+ <<"lib/encoder.ex">>,<<"lib/formatter.ex">>,<<"lib/fragment.ex">>,
9
+ <<"lib/helpers.ex">>,<<"lib/jason.ex">>,<<"mix.exs">>,<<"README.md">>,
10
+ <<"LICENSE">>,<<"CHANGELOG.md">>]}.
11
+ {<<"licenses">>,[<<"Apache 2.0">>]}.
12
+ {<<"links">>,[{<<"GitHub">>,<<"https://github.com/michalmuskala/jason">>}]}.
13
+ {<<"name">>,<<"jason">>}.
14
+ {<<"requirements">>,
15
+ [[{<<"app">>,<<"decimal">>},
16
+ {<<"name">>,<<"decimal">>},
17
+ {<<"optional">>,true},
18
+ {<<"repository">>,<<"hexpm">>},
19
+ {<<"requirement">>,<<"~> 1.0">>}]]}.
20
+ {<<"version">>,<<"1.1.2">>}.
@@ -0,0 +1,158 @@
1
+ defmodule Jason.Codegen do
2
+ @moduledoc false
3
+
4
+ alias Jason.{Encode, EncodeError}
5
+
6
+ def jump_table(ranges, default) do
7
+ ranges
8
+ |> ranges_to_orddict()
9
+ |> :array.from_orddict(default)
10
+ |> :array.to_orddict()
11
+ end
12
+
13
+ def jump_table(ranges, default, max) do
14
+ ranges
15
+ |> ranges_to_orddict()
16
+ |> :array.from_orddict(default)
17
+ |> resize(max)
18
+ |> :array.to_orddict()
19
+ end
20
+
21
+ defmacro bytecase(var, do: clauses) do
22
+ {ranges, default, literals} = clauses_to_ranges(clauses, [])
23
+
24
+ jump_table = jump_table(ranges, default)
25
+
26
+ quote do
27
+ case unquote(var) do
28
+ unquote(jump_table_to_clauses(jump_table, literals))
29
+ end
30
+ end
31
+ end
32
+
33
+ defmacro bytecase(var, max, do: clauses) do
34
+ {ranges, default, empty} = clauses_to_ranges(clauses, [])
35
+
36
+ jump_table = jump_table(ranges, default, max)
37
+
38
+ quote do
39
+ case unquote(var) do
40
+ unquote(jump_table_to_clauses(jump_table, empty))
41
+ end
42
+ end
43
+ end
44
+
45
+ def build_kv_iodata(kv, encode_args) do
46
+ elements =
47
+ kv
48
+ |> Enum.map(&encode_pair(&1, encode_args))
49
+ |> Enum.intersperse(",")
50
+
51
+ collapse_static(List.flatten(["{", elements] ++ '}'))
52
+ end
53
+
54
+ defp clauses_to_ranges([{:->, _, [[{:in, _, [byte, range]}, rest], action]} | tail], acc) do
55
+ clauses_to_ranges(tail, [{range, {byte, rest, action}} | acc])
56
+ end
57
+
58
+ defp clauses_to_ranges([{:->, _, [[default, rest], action]} | tail], acc) do
59
+ {Enum.reverse(acc), {default, rest, action}, literal_clauses(tail)}
60
+ end
61
+
62
+ defp literal_clauses(clauses) do
63
+ Enum.map(clauses, fn {:->, _, [[literal], action]} ->
64
+ {literal, action}
65
+ end)
66
+ end
67
+
68
+ defp jump_table_to_clauses([{val, {{:_, _, _}, rest, action}} | tail], empty) do
69
+ quote do
70
+ <<unquote(val), unquote(rest)::bits>> ->
71
+ unquote(action)
72
+ end ++ jump_table_to_clauses(tail, empty)
73
+ end
74
+
75
+ defp jump_table_to_clauses([{val, {byte, rest, action}} | tail], empty) do
76
+ quote do
77
+ <<unquote(byte), unquote(rest)::bits>> when unquote(byte) === unquote(val) ->
78
+ unquote(action)
79
+ end ++ jump_table_to_clauses(tail, empty)
80
+ end
81
+
82
+ defp jump_table_to_clauses([], literals) do
83
+ Enum.flat_map(literals, fn {pattern, action} ->
84
+ quote do
85
+ unquote(pattern) ->
86
+ unquote(action)
87
+ end
88
+ end)
89
+ end
90
+
91
+ defmacro jump_table_case(var, rest, ranges, default) do
92
+ clauses =
93
+ ranges
94
+ |> jump_table(default)
95
+ |> Enum.flat_map(fn {byte_value, action} ->
96
+ quote do
97
+ <<unquote(byte_value), unquote(rest)::bits>> ->
98
+ unquote(action)
99
+ end
100
+ end)
101
+
102
+ clauses = clauses ++ quote(do: (<<>> -> empty_error(original, skip)))
103
+
104
+ quote do
105
+ case unquote(var) do
106
+ unquote(clauses)
107
+ end
108
+ end
109
+ end
110
+
111
+ defp resize(array, size), do: :array.resize(size, array)
112
+
113
+ defp ranges_to_orddict(ranges) do
114
+ ranges
115
+ |> Enum.flat_map(fn
116
+ {int, value} when is_integer(int) ->
117
+ [{int, value}]
118
+
119
+ {enum, value} ->
120
+ Enum.map(enum, &{&1, value})
121
+ end)
122
+ |> :orddict.from_list()
123
+ end
124
+
125
+ defp encode_pair({key, value}, encode_args) do
126
+ key = IO.iodata_to_binary(Encode.key(key, &escape_key/3))
127
+ key = "\"" <> key <> "\":"
128
+ [key, quote(do: Encode.value(unquote(value), unquote_splicing(encode_args)))]
129
+ end
130
+
131
+ defp escape_key(binary, _original, _skip) do
132
+ check_safe_key!(binary)
133
+ binary
134
+ end
135
+
136
+ defp check_safe_key!(binary) do
137
+ for <<(<<byte>> <- binary)>> do
138
+ if byte > 0x7F or byte < 0x1F or byte in '"\\/' do
139
+ raise EncodeError,
140
+ "invalid byte #{inspect(byte, base: :hex)} in literal key: #{inspect(binary)}"
141
+ end
142
+ end
143
+
144
+ :ok
145
+ end
146
+
147
+ defp collapse_static([bin1, bin2 | rest]) when is_binary(bin1) and is_binary(bin2) do
148
+ collapse_static([bin1 <> bin2 | rest])
149
+ end
150
+
151
+ defp collapse_static([other | rest]) do
152
+ [other | collapse_static(rest)]
153
+ end
154
+
155
+ defp collapse_static([]) do
156
+ []
157
+ end
158
+ end