Skip to content

Commit e23c65b

Browse files
axelsonlukaszsamson
authored andcommitted
vendor Jason
This prevents module conflicts with the user's version of Jason since both are loaded into the same beam instance (at least until #253) is addressed.
1 parent 6a966cc commit e23c65b

25 files changed

+464
-307
lines changed

README.md

+19-19
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
# Jason
1+
# JasonVendored
22

33
A blazing fast JSON parser and generator in pure Elixir.
44

55
The parser and generator are at least twice as fast as other Elixir/Erlang libraries
66
(most notably `Poison`).
77
The performance is comparable to `jiffy`, which is implemented in C as a NIF.
8-
Jason is usually only twice as slow.
8+
JasonVendored is usually only twice as slow.
99

1010
Both parser and generator fully conform to
1111
[RFC 8259](https://tools.ietf.org/html/rfc8259) and
@@ -26,10 +26,10 @@ end
2626
## Basic Usage
2727

2828
``` elixir
29-
iex(1)> Jason.encode!(%{"age" => 44, "name" => "Steve Irwin", "nationality" => "Australian"})
29+
iex(1)> JasonVendored.encode!(%{"age" => 44, "name" => "Steve Irwin", "nationality" => "Australian"})
3030
"{\"age\":44,\"name\":\"Steve Irwin\",\"nationality\":\"Australian\"}"
3131

32-
iex(2)> Jason.decode!(~s({"age":44,"name":"Steve Irwin","nationality":"Australian"}))
32+
iex(2)> JasonVendored.decode!(~s({"age":44,"name":"Steve Irwin","nationality":"Australian"}))
3333
%{"age" => 44, "name" => "Steve Irwin", "nationality" => "Australian"}
3434
```
3535

@@ -39,17 +39,17 @@ Full documentation can be found at [https://hexdocs.pm/jason](https://hexdocs.pm
3939

4040
### Postgrex
4141

42-
Versions starting at 0.14.0 use `Jason` by default. For earlier versions, please refer to
42+
Versions starting at 0.14.0 use `JasonVendored` by default. For earlier versions, please refer to
4343
[previous versions of this document](https://github.com/michalmuskala/jason/tree/v1.1.2#postgrex).
4444

4545
### Ecto
4646

47-
Versions starting at 3.0.0 use `Jason` by default. For earlier versions, please refer to
47+
Versions starting at 3.0.0 use `JasonVendored` by default. For earlier versions, please refer to
4848
[previous versions of this document](https://github.com/michalmuskala/jason/tree/v1.1.2#ecto).
4949

5050
### Plug (and Phoenix)
5151

52-
Phoenix starting at 1.4.0 uses `Jason` by default. For earlier versions, please refer to
52+
Phoenix starting at 1.4.0 uses `JasonVendored` by default. For earlier versions, please refer to
5353
[previous versions of this document](https://github.com/michalmuskala/jason/tree/v1.1.2#plug-and-phoenix).
5454

5555
### Absinthe
@@ -60,12 +60,12 @@ You need to pass the `:json_codec` option to `Absinthe.Plug`
6060
# When called directly:
6161
plug Absinthe.Plug,
6262
schema: MyApp.Schema,
63-
json_codec: Jason
63+
json_codec: JasonVendored
6464

6565
# When used in phoenix router:
6666
forward "/api",
6767
to: Absinthe.Plug,
68-
init_opts: [schema: MyApp.Schema, json_codec: Jason]
68+
init_opts: [schema: MyApp.Schema, json_codec: JasonVendored]
6969
```
7070

7171
## Benchmarks
@@ -85,24 +85,24 @@ A HTML report of the benchmarks (after their execution) can be found in
8585

8686
## Differences to Poison
8787

88-
Jason has a couple feature differences compared to Poison.
88+
JasonVendored has a couple feature differences compared to Poison.
8989

90-
* Jason follows the JSON spec more strictly, for example it does not allow
90+
* JasonVendored follows the JSON spec more strictly, for example it does not allow
9191
unescaped newline characters in JSON strings - e.g. `"\"\n\""` will
9292
produce a decoding error.
9393
* no support for decoding into data structures (the `as:` option).
9494
* no built-in encoders for `MapSet`, `Range` and `Stream`.
9595
* no support for encoding arbitrary structs - explicit implementation
96-
of the `Jason.Encoder` protocol is always required.
96+
of the `JasonVendored.Encoder` protocol is always required.
9797
* different pretty-printing customisation options (default `pretty: true` works the same)
9898

9999
If you require encoders for any of the unsupported collection types, I suggest
100100
adding the needed implementations directly to your project:
101101

102102
```elixir
103-
defimpl Jason.Encoder, for: [MapSet, Range, Stream] do
103+
defimpl JasonVendored.Encoder, for: [MapSet, Range, Stream] do
104104
def encode(struct, opts) do
105-
Jason.Encode.list(Enum.to_list(struct), opts)
105+
JasonVendored.Encode.list(Enum.to_list(struct), opts)
106106
end
107107
end
108108
```
@@ -112,7 +112,7 @@ if you own the struct, you can derive the implementation specifying
112112
which fields should be encoded to JSON:
113113

114114
```elixir
115-
@derive {Jason.Encoder, only: [....]}
115+
@derive {JasonVendored.Encoder, only: [....]}
116116
defstruct # ...
117117
```
118118

@@ -121,21 +121,21 @@ used carefully to avoid accidentally leaking private information
121121
when new fields are added:
122122

123123
```elixir
124-
@derive Jason.Encoder
124+
@derive JasonVendored.Encoder
125125
defstruct # ...
126126
```
127127

128128
Finally, if you don't own the struct you want to encode to JSON,
129129
you may use `Protocol.derive/3` placed outside of any module:
130130

131131
```elixir
132-
Protocol.derive(Jason.Encoder, NameOfTheStruct, only: [...])
133-
Protocol.derive(Jason.Encoder, NameOfTheStruct)
132+
Protocol.derive(JasonVendored.Encoder, NameOfTheStruct, only: [...])
133+
Protocol.derive(JasonVendored.Encoder, NameOfTheStruct)
134134
```
135135

136136
## License
137137

138-
Jason is released under the Apache License 2.0 - see the [LICENSE](LICENSE) file.
138+
JasonVendored is released under the Apache License 2.0 - see the [LICENSE](LICENSE) file.
139139

140140
Some elements of tests and benchmarks have their origins in the
141141
[Poison library](https://github.com/devinus/poison) and were initially licensed under [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).

bench/decode.exs

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
decode_jobs = %{
2-
"Jason" => fn {json, _} -> Jason.decode!(json) end,
2+
"JasonVendored" => fn {json, _} -> JasonVendored.decode!(json) end,
33
"Poison" => fn {json, _} -> Poison.decode!(json) end,
4-
"JSX" => fn {json, _} -> JSX.decode!(json, [:strict]) end,
5-
"Tiny" => fn {json, _} -> Tiny.decode!(json) end,
6-
"jsone" => fn {json, _} -> :jsone.decode(json) end,
7-
"jiffy" => fn {json, _} -> :jiffy.decode(json, [:return_maps, :use_nil]) end,
8-
"JSON" => fn {json, _} -> JSON.decode!(json) end,
4+
"JSX" => fn {json, _} -> JSX.decode!(json, [:strict]) end,
5+
"Tiny" => fn {json, _} -> Tiny.decode!(json) end,
6+
"jsone" => fn {json, _} -> :jsone.decode(json) end,
7+
"jiffy" => fn {json, _} -> :jiffy.decode(json, [:return_maps, :use_nil]) end,
8+
"JSON" => fn {json, _} -> JSON.decode!(json) end
99
# "binary_to_term/1" => fn {_, etf} -> :erlang.binary_to_term(etf) end,
1010
}
1111

@@ -19,18 +19,18 @@ decode_inputs = [
1919
"JSON Generator (Pretty)",
2020
"UTF-8 escaped",
2121
"UTF-8 unescaped",
22-
"Issue 90",
22+
"Issue 90"
2323
]
2424

25-
read_data = fn (name) ->
25+
read_data = fn name ->
2626
file =
2727
name
28-
|> String.downcase
28+
|> String.downcase()
2929
|> String.replace(~r/([^\w]|-|_)+/, "-")
3030
|> String.trim("-")
3131

3232
json = File.read!(Path.expand("data/#{file}.json", __DIR__))
33-
etf = :erlang.term_to_binary(Jason.decode!(json))
33+
etf = :erlang.term_to_binary(JasonVendored.decode!(json))
3434

3535
{json, etf}
3636
end
@@ -45,7 +45,7 @@ end
4545
IO.puts("\n")
4646

4747
Benchee.run(decode_jobs,
48-
# parallel: 4,
48+
# parallel: 4,
4949
warmup: 5,
5050
time: 30,
5151
memory_time: 1,
@@ -54,6 +54,6 @@ Benchee.run(decode_jobs,
5454
load: "output/runs/*.benchee",
5555
formatters: [
5656
{Benchee.Formatters.HTML, file: Path.expand("output/decode.html", __DIR__)},
57-
Benchee.Formatters.Console,
57+
Benchee.Formatters.Console
5858
]
5959
)

bench/encode.exs

+19-19
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
encode_jobs = %{
2-
"Jason" => &Jason.encode_to_iodata!/1,
3-
"Jason strict" => &Jason.encode_to_iodata!(&1, maps: :strict),
4-
"Poison" => &Poison.encode_to_iodata!/1,
5-
"JSX" => &JSX.encode!/1,
6-
"Tiny" => &Tiny.encode!/1,
7-
"jsone" => &:jsone.encode/1,
8-
"jiffy" => &:jiffy.encode/1,
9-
"JSON" => &JSON.encode!/1,
2+
"JasonVendored" => &JasonVendored.encode_to_iodata!/1,
3+
"JasonVendored strict" => &JasonVendored.encode_to_iodata!(&1, maps: :strict),
4+
"Poison" => &Poison.encode_to_iodata!/1,
5+
"JSX" => &JSX.encode!/1,
6+
"Tiny" => &Tiny.encode!/1,
7+
"jsone" => &:jsone.encode/1,
8+
"jiffy" => &:jiffy.encode/1,
9+
"JSON" => &JSON.encode!/1
1010
# "term_to_binary" => &:erlang.term_to_binary/1,
1111
}
1212

@@ -22,28 +22,28 @@ encode_inputs = [
2222
"Canada",
2323
]
2424

25-
read_data = fn (name) ->
25+
read_data = fn name ->
2626
name
27-
|> String.downcase
27+
|> String.downcase()
2828
|> String.replace(~r/([^\w]|-|_)+/, "-")
2929
|> String.trim("-")
3030
|> (&"data/#{&1}.json").()
3131
|> Path.expand(__DIR__)
32-
|> File.read!
32+
|> File.read!()
3333
end
3434

35-
3635
Benchee.run(encode_jobs,
37-
# parallel: 4,
36+
# parallel: 4,
3837
warmup: 5,
3938
time: 30,
4039
memory_time: 1,
41-
inputs: for name <- encode_inputs, into: %{} do
42-
name
43-
|> read_data.()
44-
|> Jason.decode!()
45-
|> (&{name, &1}).()
46-
end,
40+
inputs:
41+
for name <- encode_inputs, into: %{} do
42+
name
43+
|> read_data.()
44+
|> JasonVendored.decode!()
45+
|> (&{name, &1}).()
46+
end,
4747
formatters: [
4848
{Benchee.Formatters.HTML, file: Path.expand("output/encode.html", __DIR__)},
4949
Benchee.Formatters.Console

bench/mix.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
defmodule JasonBench.MixProject do
1+
defmodule JasonVendoredBench.MixProject do
22
use Mix.Project
33

44
def project do

dialyzer.ignore

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
Unknown function 'Elixir.Jason.Encoder.Function':'__impl__'/1
2-
Unknown function 'Elixir.Jason.Encoder.PID':'__impl__'/1
3-
Unknown function 'Elixir.Jason.Encoder.Port':'__impl__'/1
4-
Unknown function 'Elixir.Jason.Encoder.Reference':'__impl__'/1
5-
Unknown function 'Elixir.Jason.Encoder.Tuple':'__impl__'/1
1+
Unknown function 'Elixir.JasonVendored.Encoder.Function':'__impl__'/1
2+
Unknown function 'Elixir.JasonVendored.Encoder.PID':'__impl__'/1
3+
Unknown function 'Elixir.JasonVendored.Encoder.Port':'__impl__'/1
4+
Unknown function 'Elixir.JasonVendored.Encoder.Reference':'__impl__'/1
5+
Unknown function 'Elixir.JasonVendored.Encoder.Tuple':'__impl__'/1

lib/codegen.ex

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
defmodule Jason.Codegen do
1+
defmodule JasonVendored.Codegen do
22
@moduledoc false
33

4-
alias Jason.{Encode, EncodeError}
4+
alias JasonVendored.{Encode, EncodeError}
55

66
def jump_table(ranges, default) do
77
ranges
@@ -93,12 +93,12 @@ defmodule Jason.Codegen do
9393
defp ranges_to_orddict(ranges) do
9494
ranges
9595
|> Enum.flat_map(fn
96-
{int, value} when is_integer(int) ->
97-
[{int, value}]
96+
{int, value} when is_integer(int) ->
97+
[{int, value}]
9898

99-
{enum, value} ->
100-
Enum.map(enum, &{&1, value})
101-
end)
99+
{enum, value} ->
100+
Enum.map(enum, &{&1, value})
101+
end)
102102
|> :orddict.from_list()
103103
end
104104

0 commit comments

Comments
 (0)