Skip to content

Commit fc5ef15

Browse files
committed
chore: updated README and added missing decode option flags to yecc
backend
1 parent b42745c commit fc5ef15

File tree

6 files changed

+61
-7
lines changed

6 files changed

+61
-7
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,7 @@ json5-*.tar
2424

2525
# Temporary files, for example, from tests.
2626
/tmp/
27+
28+
# auto generated files
29+
src/lexer.erl
30+
src/parser.erl

lib/json5.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ defmodule Json5 do
1818
- if none of the above options are set return the key as a binary (String.t())
1919
- object_new_function: ({any, any}) -> any
2020
- function to create a map from the list of parsed tuples, by default uses `Map.new/1`
21+
- backend: [`Json5.Decode.Backend.Combine`, `Json5.Decode.Backend.Yecc`]
22+
- select the backend to be used (Defaults to Combine).
23+
- The Combine backend is coded with the json5 spec (with unicode) in mind, but a lot slower (about 2000x slower than `Jason`)
24+
- The Yecc backend is a lot faster (about 6x slower than `Jason`) but not that rigorous based on the json5 spec. It is just written to make the existing tests work.
2125
2226
```elixir
2327
iex> Json5.decode("{array: [1, 2, 3], map: {'null': null, test: 1, }, }")

lib/json5/decode/backend/yecc.ex

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,13 @@ defmodule Json5.Decode.Backend.Yecc do
3838
end
3939

4040
defp to_term({:map, _, key_value_list}, config) do
41-
Map.new(key_value_list, fn {key, value} ->
41+
func = Map.get(config, :object_new_function, &Map.new/1)
42+
43+
key_value_list
44+
|> Enum.map(fn {key, value} ->
4245
{to_term(key, config), to_term(value, config)}
4346
end)
47+
|> func.()
4448
end
4549

4650
defp to_term({:list, _, list}, config) do
@@ -64,6 +68,10 @@ defmodule Json5.Decode.Backend.Yecc do
6468
String.to_existing_atom(key)
6569
end
6670

71+
def do_key_term(key, %{object_key_atom: true}) do
72+
String.to_existing_atom(key)
73+
end
74+
6775
def do_key_term(key, %{object_key_function: object_key_function}) do
6876
object_key_function.(key)
6977
end

mix.exs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ defmodule Json5.MixProject do
44
def project do
55
[
66
app: :json5,
7-
version: "0.1.0",
7+
version: "0.2.0",
88
elixir: "~> 1.10",
99
description: "Json5 in Elixir",
1010
start_permanent: Mix.env() == :prod,
@@ -14,14 +14,12 @@ defmodule Json5.MixProject do
1414
]
1515
end
1616

17-
# Run "mix help compile.app" to learn about applications.
1817
def application do
1918
[
2019
extra_applications: [:logger]
2120
]
2221
end
2322

24-
# Run "mix help deps" to learn about dependencies.
2523
defp deps do
2624
[
2725
{:ex_doc, "~> 0.24", only: :dev, runtime: false},

src/lexer.xrl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Definitions.
2+
23
Digit = [0-9]
34
HexDigit = [0-9a-fA-F]
45
Float = (\+|-)?{Digit}+\.?{Digit}+?((E|e)(\+|-)?{Digit}+)?
@@ -38,9 +39,8 @@ false : {token, {boolean, TokenLine, false}}.
3839
%% multiline comment
3940
/\*[^(*/)]*\*/ : skip_token.
4041

41-
42-
4342
Erlang code.
43+
4444
strip_quotes(Str) ->
4545
tl(lists:droplast(Str)).
4646

test/json5/decode_test.exs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ defmodule Json5.DecodeTest do
204204
assert {:error, _} = Json5.decode(input, backend: @backend)
205205
end
206206

207-
test "decode atom object" do
207+
test "decode existing atom object" do
208208
input = """
209209
{
210210
test: 1,
@@ -224,6 +224,46 @@ defmodule Json5.DecodeTest do
224224
)
225225
end
226226

227+
test "decode atom object" do
228+
input = """
229+
{
230+
test: 1,
231+
other: null,
232+
}
233+
"""
234+
235+
expected = %{
236+
test: Decimal.new(1),
237+
other: nil
238+
}
239+
240+
assert {:ok, expected} ==
241+
Json5.decode(input,
242+
object_key_atom: true,
243+
backend: @backend
244+
)
245+
end
246+
247+
test "decode object with object new function" do
248+
input = """
249+
{
250+
test: 1,
251+
other: null,
252+
}
253+
"""
254+
255+
expected = [
256+
{"test", Decimal.new(1)},
257+
{"other", nil}
258+
]
259+
260+
assert {:ok, expected} ==
261+
Json5.decode(input,
262+
object_new_function: &Enum.to_list/1,
263+
backend: @backend
264+
)
265+
end
266+
227267
test "decode object with key function" do
228268
input = """
229269
{

0 commit comments

Comments
 (0)