dependabot-hex 0.95.70 → 0.95.71
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- metadata +4 -19
- data/helpers/deps/jason/.fetch +0 -0
- data/helpers/deps/jason/.hex +0 -2
- data/helpers/deps/jason/CHANGELOG.md +0 -60
- data/helpers/deps/jason/LICENSE +0 -13
- data/helpers/deps/jason/README.md +0 -179
- data/helpers/deps/jason/hex_metadata.config +0 -20
- data/helpers/deps/jason/lib/codegen.ex +0 -158
- data/helpers/deps/jason/lib/decoder.ex +0 -657
- data/helpers/deps/jason/lib/encode.ex +0 -630
- data/helpers/deps/jason/lib/encoder.ex +0 -216
- data/helpers/deps/jason/lib/formatter.ex +0 -253
- data/helpers/deps/jason/lib/fragment.ex +0 -11
- data/helpers/deps/jason/lib/helpers.ex +0 -90
- data/helpers/deps/jason/lib/jason.ex +0 -228
- data/helpers/deps/jason/mix.exs +0 -92
@@ -1,216 +0,0 @@
|
|
1
|
-
defprotocol Jason.Encoder do
|
2
|
-
@moduledoc """
|
3
|
-
Protocol controlling how a value is encoded to JSON.
|
4
|
-
|
5
|
-
## Deriving
|
6
|
-
|
7
|
-
The protocol allows leveraging the Elixir's `@derive` feature
|
8
|
-
to simplify protocol implementation in trivial cases. Accepted
|
9
|
-
options are:
|
10
|
-
|
11
|
-
* `:only` - encodes only values of specified keys.
|
12
|
-
* `:except` - encodes all struct fields except specified keys.
|
13
|
-
|
14
|
-
By default all keys except the `:__struct__` key are encoded.
|
15
|
-
|
16
|
-
## Example
|
17
|
-
|
18
|
-
Let's assume a presence of the following struct:
|
19
|
-
|
20
|
-
defmodule Test do
|
21
|
-
defstruct [:foo, :bar, :baz]
|
22
|
-
end
|
23
|
-
|
24
|
-
If we were to call `@derive Jason.Encoder` just before `defstruct`,
|
25
|
-
an implementaion similar to the follwing implementation would be generated:
|
26
|
-
|
27
|
-
defimpl Jason.Encoder, for: Test do
|
28
|
-
def encode(value, opts) do
|
29
|
-
Jason.Encode.map(Map.take(value, [:foo, :bar, :baz]), opts)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
If we called `@derive {Jason.Encoder, only: [:foo]}`, an implementation
|
34
|
-
similar to the following implementation would be genrated:
|
35
|
-
|
36
|
-
defimpl Jason.Encoder, for: Test do
|
37
|
-
def encode(value, opts) do
|
38
|
-
Jason.Encode.map(Map.take(value, [:foo]), opts)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
If we called `@derive {Jason.Encoder, except: [:foo]}`, an implementation
|
43
|
-
similar to the following implementation would be generated:
|
44
|
-
|
45
|
-
defimpl Jason.Encoder, for: Test do
|
46
|
-
def encode(value, opts) do
|
47
|
-
Jason.Encode.map(Map.take(value, [:bar, :baz]), opts)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
The actually generated implementations are more efficient computing some data
|
52
|
-
during compilation similar to the macros from the `Jason.Helpers` module.
|
53
|
-
|
54
|
-
## Explicit implementation
|
55
|
-
|
56
|
-
If you wish to implement the protocol fully yourself, it is advised to
|
57
|
-
use functions from the `Jason.Encode` module to do the actual iodata
|
58
|
-
generation - they are highly optimized and verified to always produce
|
59
|
-
valid JSON.
|
60
|
-
"""
|
61
|
-
|
62
|
-
@type t :: term
|
63
|
-
@type opts :: Jason.Encode.opts()
|
64
|
-
|
65
|
-
@fallback_to_any true
|
66
|
-
|
67
|
-
@doc """
|
68
|
-
Encodes `value` to JSON.
|
69
|
-
|
70
|
-
The argument `opts` is opaque - it can be passed to various functions in
|
71
|
-
`Jason.Encode` (or to the protocol function itself) for encoding values to JSON.
|
72
|
-
"""
|
73
|
-
@spec encode(t, opts) :: iodata
|
74
|
-
def encode(value, opts)
|
75
|
-
end
|
76
|
-
|
77
|
-
defimpl Jason.Encoder, for: Any do
|
78
|
-
defmacro __deriving__(module, struct, opts) do
|
79
|
-
fields = fields_to_encode(struct, opts)
|
80
|
-
kv = Enum.map(fields, &{&1, generated_var(&1, __MODULE__)})
|
81
|
-
escape = quote(do: escape)
|
82
|
-
encode_map = quote(do: encode_map)
|
83
|
-
encode_args = [escape, encode_map]
|
84
|
-
kv_iodata = Jason.Codegen.build_kv_iodata(kv, encode_args)
|
85
|
-
|
86
|
-
quote do
|
87
|
-
defimpl Jason.Encoder, for: unquote(module) do
|
88
|
-
require Jason.Helpers
|
89
|
-
|
90
|
-
def encode(%{unquote_splicing(kv)}, {unquote(escape), unquote(encode_map)}) do
|
91
|
-
unquote(kv_iodata)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
# The same as Macro.var/2 except it sets generated: true
|
98
|
-
defp generated_var(name, context) do
|
99
|
-
{name, [generated: true], context}
|
100
|
-
end
|
101
|
-
|
102
|
-
def encode(%_{} = struct, _opts) do
|
103
|
-
raise Protocol.UndefinedError,
|
104
|
-
protocol: @protocol,
|
105
|
-
value: struct,
|
106
|
-
description: """
|
107
|
-
Jason.Encoder protocol must always be explicitly implemented.
|
108
|
-
|
109
|
-
If you own the struct, you can derive the implementation specifying \
|
110
|
-
which fields should be encoded to JSON:
|
111
|
-
|
112
|
-
@derive {Jason.Encoder, only: [....]}
|
113
|
-
defstruct ...
|
114
|
-
|
115
|
-
It is also possible to encode all fields, although this should be \
|
116
|
-
used carefully to avoid accidentally leaking private information \
|
117
|
-
when new fields are added:
|
118
|
-
|
119
|
-
@derive Jason.Encoder
|
120
|
-
defstruct ...
|
121
|
-
|
122
|
-
Finally, if you don't own the struct you want to encode to JSON, \
|
123
|
-
you may use Protocol.derive/3 placed outside of any module:
|
124
|
-
|
125
|
-
Protocol.derive(Jason.Encoder, NameOfTheStruct, only: [...])
|
126
|
-
Protocol.derive(Jason.Encoder, NameOfTheStruct)
|
127
|
-
"""
|
128
|
-
end
|
129
|
-
|
130
|
-
def encode(value, _opts) do
|
131
|
-
raise Protocol.UndefinedError,
|
132
|
-
protocol: @protocol,
|
133
|
-
value: value,
|
134
|
-
description: "Jason.Encoder protocol must always be explicitly implemented"
|
135
|
-
end
|
136
|
-
|
137
|
-
defp fields_to_encode(struct, opts) do
|
138
|
-
cond do
|
139
|
-
only = Keyword.get(opts, :only) ->
|
140
|
-
only
|
141
|
-
|
142
|
-
except = Keyword.get(opts, :except) ->
|
143
|
-
Map.keys(struct) -- [:__struct__ | except]
|
144
|
-
|
145
|
-
true ->
|
146
|
-
Map.keys(struct) -- [:__struct__]
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
# The following implementations are formality - they are already covered
|
152
|
-
# by the main encoding mechanism in Jason.Encode, but exist mostly for
|
153
|
-
# documentation purposes and if anybody had the idea to call the protocol directly.
|
154
|
-
|
155
|
-
defimpl Jason.Encoder, for: Atom do
|
156
|
-
def encode(atom, opts) do
|
157
|
-
Jason.Encode.atom(atom, opts)
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
defimpl Jason.Encoder, for: Integer do
|
162
|
-
def encode(integer, _opts) do
|
163
|
-
Jason.Encode.integer(integer)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
defimpl Jason.Encoder, for: Float do
|
168
|
-
def encode(float, _opts) do
|
169
|
-
Jason.Encode.float(float)
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
defimpl Jason.Encoder, for: List do
|
174
|
-
def encode(list, opts) do
|
175
|
-
Jason.Encode.list(list, opts)
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
defimpl Jason.Encoder, for: Map do
|
180
|
-
def encode(map, opts) do
|
181
|
-
Jason.Encode.map(map, opts)
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
defimpl Jason.Encoder, for: BitString do
|
186
|
-
def encode(binary, opts) when is_binary(binary) do
|
187
|
-
Jason.Encode.string(binary, opts)
|
188
|
-
end
|
189
|
-
|
190
|
-
def encode(bitstring, _opts) do
|
191
|
-
raise Protocol.UndefinedError,
|
192
|
-
protocol: @protocol,
|
193
|
-
value: bitstring,
|
194
|
-
description: "cannot encode a bitstring to JSON"
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
defimpl Jason.Encoder, for: [Date, Time, NaiveDateTime, DateTime] do
|
199
|
-
def encode(value, _opts) do
|
200
|
-
[?\", @for.to_iso8601(value), ?\"]
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
defimpl Jason.Encoder, for: Decimal do
|
205
|
-
def encode(value, _opts) do
|
206
|
-
# silence the xref warning
|
207
|
-
decimal = Decimal
|
208
|
-
[?\", decimal.to_string(value), ?\"]
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
defimpl Jason.Encoder, for: Jason.Fragment do
|
213
|
-
def encode(%{encode: encode}, opts) do
|
214
|
-
encode.(opts)
|
215
|
-
end
|
216
|
-
end
|
@@ -1,253 +0,0 @@
|
|
1
|
-
defmodule Jason.Formatter do
|
2
|
-
@moduledoc ~S"""
|
3
|
-
Pretty-printing and minimizing functions for JSON-encoded data.
|
4
|
-
|
5
|
-
Input is required to be in an 8-bit-wide encoding such as UTF-8 or Latin-1
|
6
|
-
in `t:iodata/0` format. Input must ve valid JSON, invalid JSON may produce
|
7
|
-
unexpected results or errors.
|
8
|
-
"""
|
9
|
-
|
10
|
-
@type opts :: [
|
11
|
-
{:indent, iodata}
|
12
|
-
| {:line_separator, iodata}
|
13
|
-
| {:record_separator, iodata}
|
14
|
-
| {:after_colon, iodata}
|
15
|
-
]
|
16
|
-
|
17
|
-
import Record
|
18
|
-
defrecordp :opts, [:indent, :line, :record, :colon]
|
19
|
-
|
20
|
-
@doc ~S"""
|
21
|
-
Pretty-prints JSON-encoded `input`.
|
22
|
-
|
23
|
-
`input` may contain multiple JSON objects or arrays, optionally separated
|
24
|
-
by whitespace (e.g., one object per line). Objects in output will be
|
25
|
-
separated by newlines. No trailing newline is emitted.
|
26
|
-
|
27
|
-
## Options
|
28
|
-
|
29
|
-
* `:indent` - used for nested objects and arrays (default: two spaces - `" "`);
|
30
|
-
* `:line_separator` - used in nested objects (default: `"\n"`);
|
31
|
-
* `:record_separator` - separates root-level objects and arrays
|
32
|
-
(default is the value for `:line_separator` option);
|
33
|
-
* `:after_colon` - printed after a colon inside objects (default: one space - `" "`).
|
34
|
-
|
35
|
-
## Examples
|
36
|
-
|
37
|
-
iex> Jason.Formatter.pretty_print(~s|{"a":{"b": [1, 2]}}|)
|
38
|
-
~s|{
|
39
|
-
"a": {
|
40
|
-
"b": [
|
41
|
-
1,
|
42
|
-
2
|
43
|
-
]
|
44
|
-
}
|
45
|
-
}|
|
46
|
-
|
47
|
-
"""
|
48
|
-
@spec pretty_print(iodata, opts) :: binary
|
49
|
-
def pretty_print(input, opts \\ []) do
|
50
|
-
input
|
51
|
-
|> pretty_print_to_iodata(opts)
|
52
|
-
|> IO.iodata_to_binary()
|
53
|
-
end
|
54
|
-
|
55
|
-
@doc ~S"""
|
56
|
-
Pretty-prints JSON-encoded `input` and returns iodata.
|
57
|
-
|
58
|
-
This function should be preferred to `pretty_print/2`, if the pretty-printed
|
59
|
-
JSON will be handed over to one of the IO functions or sent
|
60
|
-
over the socket. The Erlang runtime is able to leverage vectorised
|
61
|
-
writes and avoid allocating a continuous buffer for the whole
|
62
|
-
resulting string, lowering memory use and increasing performance.
|
63
|
-
"""
|
64
|
-
@spec pretty_print_to_iodata(iodata, opts) :: iodata
|
65
|
-
def pretty_print_to_iodata(input, opts \\ []) do
|
66
|
-
opts = parse_opts(opts, " ", "\n", nil, " ")
|
67
|
-
|
68
|
-
depth = :first
|
69
|
-
empty = false
|
70
|
-
|
71
|
-
{output, _state} = pp_iodata(input, [], depth, empty, opts)
|
72
|
-
|
73
|
-
output
|
74
|
-
end
|
75
|
-
|
76
|
-
@doc ~S"""
|
77
|
-
Minimizes JSON-encoded `input`.
|
78
|
-
|
79
|
-
`input` may contain multiple JSON objects or arrays, optionally
|
80
|
-
separated by whitespace (e.g., one object per line). Minimized
|
81
|
-
output will contain one object per line. No trailing newline is emitted.
|
82
|
-
|
83
|
-
## Options
|
84
|
-
|
85
|
-
* `:record_separator` - controls the string used as newline (default: `"\n"`).
|
86
|
-
|
87
|
-
## Examples
|
88
|
-
|
89
|
-
iex> Jason.Formatter.minimize(~s|{ "a" : "b" , "c": \n\n 2}|)
|
90
|
-
~s|{"a":"b","c":2}|
|
91
|
-
|
92
|
-
"""
|
93
|
-
@spec minimize(iodata, opts) :: binary
|
94
|
-
def minimize(input, opts \\ []) do
|
95
|
-
input
|
96
|
-
|> minimize_to_iodata(opts)
|
97
|
-
|> IO.iodata_to_binary()
|
98
|
-
end
|
99
|
-
|
100
|
-
@doc ~S"""
|
101
|
-
Minimizes JSON-encoded `input` and returns iodata.
|
102
|
-
|
103
|
-
This function should be preferred to `minimize/2`, if the minimized
|
104
|
-
JSON will be handed over to one of the IO functions or sent
|
105
|
-
over the socket. The Erlang runtime is able to leverage vectorised
|
106
|
-
writes and avoid allocating a continuous buffer for the whole
|
107
|
-
resulting string, lowering memory use and increasing performance.
|
108
|
-
"""
|
109
|
-
@spec minimize_to_iodata(iodata, opts) :: iodata
|
110
|
-
def minimize_to_iodata(input, opts) do
|
111
|
-
record = Keyword.get(opts, :record_separator, "\n")
|
112
|
-
opts = opts(indent: "", line: "", record: record, colon: "")
|
113
|
-
|
114
|
-
depth = :first
|
115
|
-
empty = false
|
116
|
-
|
117
|
-
{output, _state} = pp_iodata(input, [], depth, empty, opts)
|
118
|
-
|
119
|
-
output
|
120
|
-
end
|
121
|
-
|
122
|
-
defp parse_opts([{option, value} | opts], indent, line, record, colon) do
|
123
|
-
value = IO.iodata_to_binary(value)
|
124
|
-
case option do
|
125
|
-
:indent -> parse_opts(opts, value, line, record, colon)
|
126
|
-
:record_separator -> parse_opts(opts, indent, line, value, colon)
|
127
|
-
:after_colon -> parse_opts(opts, indent, line, record, value)
|
128
|
-
:line_separator -> parse_opts(opts, indent, value, record || value, colon)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
defp parse_opts([], indent, line, record, colon) do
|
133
|
-
opts(indent: indent, line: line, record: record || line, colon: colon)
|
134
|
-
end
|
135
|
-
|
136
|
-
for depth <- 1..16 do
|
137
|
-
defp tab(" ", unquote(depth)), do: unquote(String.duplicate(" ", depth))
|
138
|
-
end
|
139
|
-
|
140
|
-
defp tab("", _), do: ""
|
141
|
-
defp tab(indent, depth), do: List.duplicate(indent, depth)
|
142
|
-
|
143
|
-
defp pp_iodata(<<>>, output_acc, depth, empty, opts) do
|
144
|
-
{output_acc, &pp_iodata(&1, &2, depth, empty, opts)}
|
145
|
-
end
|
146
|
-
|
147
|
-
defp pp_iodata(<<byte, rest::binary>>, output_acc, depth, empty, opts) do
|
148
|
-
pp_byte(byte, rest, output_acc, depth, empty, opts)
|
149
|
-
end
|
150
|
-
|
151
|
-
defp pp_iodata([], output_acc, depth, empty, opts) do
|
152
|
-
{output_acc, &pp_iodata(&1, &2, depth, empty, opts)}
|
153
|
-
end
|
154
|
-
|
155
|
-
defp pp_iodata([byte | rest], output_acc, depth, empty, opts) when is_integer(byte) do
|
156
|
-
pp_byte(byte, rest, output_acc, depth, empty, opts)
|
157
|
-
end
|
158
|
-
|
159
|
-
defp pp_iodata([head | tail], output_acc, depth, empty, opts) do
|
160
|
-
{output_acc, cont} = pp_iodata(head, output_acc, depth, empty, opts)
|
161
|
-
cont.(tail, output_acc)
|
162
|
-
end
|
163
|
-
|
164
|
-
defp pp_byte(byte, rest, output, depth, empty, opts) when byte in ' \n\r\t' do
|
165
|
-
pp_iodata(rest, output, depth, empty, opts)
|
166
|
-
end
|
167
|
-
|
168
|
-
defp pp_byte(byte, rest, output, depth, empty, opts) when byte in '{[' do
|
169
|
-
{out, depth} =
|
170
|
-
cond do
|
171
|
-
depth == :first -> {byte, 1}
|
172
|
-
depth == 0 -> {[opts(opts, :record), byte], 1}
|
173
|
-
empty -> {[opts(opts, :line), tab(opts(opts, :indent), depth), byte], depth + 1}
|
174
|
-
true -> {byte, depth + 1}
|
175
|
-
end
|
176
|
-
|
177
|
-
empty = true
|
178
|
-
pp_iodata(rest, [output, out], depth, empty, opts)
|
179
|
-
end
|
180
|
-
|
181
|
-
defp pp_byte(byte, rest, output, depth, true = _empty, opts) when byte in '}]' do
|
182
|
-
empty = false
|
183
|
-
depth = depth - 1
|
184
|
-
pp_iodata(rest, [output, byte], depth, empty, opts)
|
185
|
-
end
|
186
|
-
|
187
|
-
defp pp_byte(byte, rest, output, depth, false = empty, opts) when byte in '}]' do
|
188
|
-
depth = depth - 1
|
189
|
-
out = [opts(opts, :line), tab(opts(opts, :indent), depth), byte]
|
190
|
-
pp_iodata(rest, [output, out], depth, empty, opts)
|
191
|
-
end
|
192
|
-
|
193
|
-
defp pp_byte(byte, rest, output, depth, _empty, opts) when byte in ',' do
|
194
|
-
empty = false
|
195
|
-
out = [byte, opts(opts, :line), tab(opts(opts, :indent), depth)]
|
196
|
-
pp_iodata(rest, [output, out], depth, empty, opts)
|
197
|
-
end
|
198
|
-
|
199
|
-
defp pp_byte(byte, rest, output, depth, empty, opts) when byte in ':' do
|
200
|
-
out = [byte, opts(opts, :colon)]
|
201
|
-
pp_iodata(rest, [output, out], depth, empty, opts)
|
202
|
-
end
|
203
|
-
|
204
|
-
defp pp_byte(byte, rest, output, depth, empty, opts) do
|
205
|
-
out = if empty, do: [opts(opts, :line), tab(opts(opts, :indent), depth), byte], else: byte
|
206
|
-
empty = false
|
207
|
-
|
208
|
-
if byte == ?" do
|
209
|
-
pp_string(rest, [output, out], _in_bs = false, &pp_iodata(&1, &2, depth, empty, opts))
|
210
|
-
else
|
211
|
-
pp_iodata(rest, [output, out], depth, empty, opts)
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
defp pp_string(<<>>, output_acc, in_bs, cont) do
|
216
|
-
{output_acc, &pp_string(&1, &2, in_bs, cont)}
|
217
|
-
end
|
218
|
-
|
219
|
-
defp pp_string(binary, output_acc, true = _in_bs, cont) when is_binary(binary) do
|
220
|
-
<<byte, rest::binary>> = binary
|
221
|
-
pp_string(rest, [output_acc, byte], false, cont)
|
222
|
-
end
|
223
|
-
|
224
|
-
defp pp_string(binary, output_acc, false = _in_bs, cont) when is_binary(binary) do
|
225
|
-
case :binary.match(binary, ["\"", "\\"]) do
|
226
|
-
:nomatch ->
|
227
|
-
{[output_acc | binary], &pp_string(&1, &2, false, cont)}
|
228
|
-
{pos, 1} ->
|
229
|
-
{head, tail} = :erlang.split_binary(binary, pos + 1)
|
230
|
-
case :binary.at(binary, pos) do
|
231
|
-
?\\ -> pp_string(tail, [output_acc | head], true, cont)
|
232
|
-
?" -> cont.(tail, [output_acc | head])
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
defp pp_string([], output_acc, in_bs, cont) do
|
238
|
-
{output_acc, &pp_string(&1, &2, in_bs, cont)}
|
239
|
-
end
|
240
|
-
|
241
|
-
defp pp_string([byte | rest], output_acc, in_bs, cont) when is_integer(byte) do
|
242
|
-
cond do
|
243
|
-
in_bs -> pp_string(rest, [output_acc, byte], false, cont)
|
244
|
-
byte == ?" -> cont.(rest, [output_acc, byte])
|
245
|
-
true -> pp_string(rest, [output_acc, byte], byte == ?\\, cont)
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
defp pp_string([head | tail], output_acc, in_bs, cont) do
|
250
|
-
{output_acc, cont} = pp_string(head, output_acc, in_bs, cont)
|
251
|
-
cont.(tail, output_acc)
|
252
|
-
end
|
253
|
-
end
|