JSON for Lua
Starting with version 2.0, the WebMCP framework contains a JSON library for Lua that can also be used independently of WebMCP.
Design goals & features
- Good performance due to implementation in C
- Utilize the Lua type system (tables, strings, numbers, booleans) to directly represent JSON values:
json.export{key1=17, key2={"arrayentry1", "arrayentry2"}, key3=true} - Allow explicit conversion from Lua tables to JSON objects/arrays to avoid ambiguity of the empty table:
json.export{emptyarray = json.array{}, emptyobject = json.object{}}
(json.array and json.object do not modify their argument but return a new value) - Path based reading:
json.get(json.import('{"a":{"b":3}}'), "a", "b") == 3
json.get(json.import('{"a":{"b":3}}'), "c", "d") == nil - Path based writing:
local obj = {a = {b = 3}}; json.set(obj, 7, 'c', 'd')
print(json.export(obj)) -- prints {"a":{"b":3},"c":{"d":7}} - Support for JSON null values:
- Return nil when accessing a JSON null value:
if json.import('{"key":null}').key then ... -- won't execute
if json.import('{"key":true}').key then ... -- will execute
(Note: In Lua anything but nil and false is considered as true.) - Allow testing for null values:
json.type(json.import('{"key":null}'), "key") == "null" - Iterate over null values:
for i, v in ipairs(json.import('[1,2,null,4]')) do print(v) end
-- prints 1 2 nil 4 - Support for setting null values:
json.export{key=json.null} == '{"key":null}' -- in table
local obj = json.object{}; obj.key = json.null -- in setter
(When using JSON objects or arrays instead of tables, reading a value after setting it to json.null will also return nil.)
- Return nil when accessing a JSON null value:
- Deterministic (i.e. sorted) output of object keys:
json.export{b=2, a=1, c=3} == '{"a":1,"b":2,"c":3}' - Pretty printing with indentation:
json.export({key1="value1", key2={"a", "b"}}, " ") -- returns:
{
"key1": "value1",
"key2": [
"a",
"b"
]
} - Import and export of deeply nested documents:
json.import('{{{ ... up to 2^30 nested levels ... }}}')
-- works if enough memory
json.import('{{{ ... more than 2^30 nested levels ... }}}')
-- returns nil plus error message
(Support for 230 nested levels assures that documents up to 231 Byte = 2 GiB can always be processed as long as enough memory is available) - Support of Unicode escape sequences:
- Bytes ≥ 128 (0x80..0xFF) are passed through (binary safe, no sanitizing)
- Conversion of escaped UTF-16 surrogates to UTF-8:
json.import('"\\uD83D\\uDE0E"') == "\xf0\x9f\x98\x8e"
-- U+1F60E: SMILING FACE WITH SUNGLASSES 😎 - Rejection of illegal UTF-16 surrogates in escape sequences:
json.import('"\\uD83D"')
-- returns nil plus error message:
-- "Illegal UTF-16 surrogate in JSON string escape sequence" - When encoding strings, only the following escape sequences are used:
\u0000 through \u0007,
\b, \t, \v, \n, \v, \f, \r,
\u000E through \u001F,
\u007F
Dependencies
Download
WebMCP's JSON library for Lua is part of WebMCP (directory "libraries/json/" in the source tarball).