2 Licensed according to the included 'LICENSE' document
3 Author: Thomas Harning Jr <harningt@gmail.com>
5 local lpeg
= require("lpeg")
9 local object
= require("json.decode.object")
10 local array
= require("json.decode.array")
12 local merge
= require("json.util").merge
13 local util
= require("json.decode.util")
15 local setmetatable
, getmetatable
= setmetatable
, getmetatable
17 local ipairs
, pairs
= ipairs
, pairs
18 local string_char
= string.char
20 local require
= require
23 local modulesToLoad
= {
31 local loadedModules
= {
35 unicodeWhitespace
= true,
39 local modes_defined
= { "default", "strict", "simple" }
44 unicodeWhitespace
= true,
48 -- Register generic value type
49 util
.register_type("VALUE")
50 for _
,name
in ipairs(modulesToLoad
) do
51 local mod = require("json.decode." .. name
)
52 for _
, mode
in pairs(modes_defined
) do
54 _M
[mode
][name
] = mod[mode
]
57 loadedModules
[name
] = mod
59 if mod.register_types
then
64 -- Shift over default into defaultOptions to permit build optimization
65 local defaultOptions
= default
69 local function buildDecoder(mode
)
70 mode
= mode
and merge({}, defaultOptions
, mode
) or defaultOptions
71 local ignored
= mode
.unicodeWhitespace
and util
.unicode_ignored
or util
.ascii_ignored
72 -- Store 'ignored' in the global options table
73 mode
.ignored
= ignored
75 local value_id
= util
.types
.VALUE
76 local value_type
= lpeg
.V(value_id
)
77 local object_type
= lpeg
.V(util
.types
.OBJECT
)
78 local array_type
= lpeg
.V(util
.types
.ARRAY
)
80 [1] = mode
.initialObject
and (ignored
* (object_type
+ array_type
)) or value_type
82 for _
, name
in pairs(modulesToLoad
) do
83 local mod = loadedModules
[name
]
84 mod.load_types(mode
[name
], mode
, grammar
)
86 -- HOOK VALUE TYPE WITH WHITESPACE
87 grammar
[value_id
] = ignored
* grammar
[value_id
] * ignored
88 grammar
= lpeg
.P(grammar
) * ignored
* -1
90 local ret
, err
= lpeg
.match(grammar
, data
)
91 assert(nil ~= ret
, err
or "Invalid JSON data")
96 local strictDecoder
, defaultDecoder
= buildDecoder(strict
), buildDecoder(default
)
99 number => number decode options
100 string => string decode options
101 array => array decode options
102 object => object decode options
103 initialObject => whether or not to require the initial object to be a table/array
104 allowUndefined => whether or not to allow undefined values
106 function getDecoder(mode
)
107 mode
= mode
== true and strict
or mode
or default
108 if mode
== strict
and strictDecoder
then
110 elseif mode
== default
and defaultDecoder
then
111 return defaultDecoder
113 return buildDecoder(mode
)
116 function decode(data
, mode
)
117 local decoder
= getDecoder(mode
)
121 local mt
= getmetatable(_M
) or {}
122 mt
.__call
= function(self
, ...)