Модуль json
Модуль json определяет процедуры работы с форматом JSON. Он создан на
основе модуля Lua-CJSON от Mark
Pulford. Полное
руководство по Lua-CJSON включено в официальную
документацию.
Ниже приведен перечень всех функций и элементов модуля json.
Имя | Назначение |
|---|---|
Преобразование Lua-объекта в JSON-строку | |
Преобразование JSON-строки в Lua-объект | |
Задание структуры вывода | |
Изменение конфигурации | |
Аналог значения "nil" в Lua |
Конвертация Lua-объекта в JSON-строку.
Параметры:
lua-value— скалярное значение или Lua-таблицаconfiguration— см. json.cfg
Возвращает
исходное значение, преобразованное в JSON-строку.
Тип возвращаемого значения
string
Пример:
tarantool> json=require('json')---...tarantool> json.encode(123)---- '123'...tarantool> json.encode({123})---- '[123]'...tarantool> json.encode({123, 234, 345})---- '[123,234,345]'...tarantool> json.encode({abc = 234, cde = 345})---- '{"cde":345,"abc":234}'...tarantool> json.encode({hello = {'world'}})---- '{"hello":["world"]}'...
Конвертация JSON-строки в Lua-объект.
Параметры:
string(string) — строка в формате JSONconfiguration— см. json.cfg
Возвращает
исходное содержимое, преобразованное в Lua-таблицу.
Тип возвращаемого значения
table
Пример:
tarantool> json = require('json')---...tarantool> json.decode('123')---- 123...tarantool> json.decode('[123, "hello"]')---- [123, 'hello']...tarantool> json.decode('{"hello": "world"}').hello---- world...
Чтобы увидеть применение json.decode() в приложении, см.
практическое задание
Подсчет суммы по JSON-полям во всех кортежах.
Задание структуры вывода.
Структуру JSON-вывода можно указать с помощью __serialize:
- 'seq', 'sequence', 'array' — таблица кодируется как массив
- 'map', 'mapping' — таблица кодируется как отображение (map)
- function — метаметод, вызываемый для извлечения сериализуемого представления таблиц, объектов cdata или userdata
Сериализация 'A' и 'B' с различными значениями __serialize даёт
разные результаты:
tarantool> json.encode(setmetatable({'A', 'B'}, { __serialize="seq"}))---- '["A","B"]'...tarantool> json.encode(setmetatable({'A', 'B'}, { __serialize="map"}))---- '{"1":"A","2":"B"}'...tarantool> json.encode({setmetatable({f1 = 'A', f2 = 'B'}, { __serialize="map"})})---- '[{"f2":"B","f1":"A"}]'...tarantool> json.encode({setmetatable({f1 = 'A', f2 = 'B'}, { __serialize="seq"})})---- '[]'...
Задание значений, влияющих на поведение json.encode и json.decode.
Все значения являются либо целыми числами, либо логическими
true/false.
Параметр | По умолчанию | Назначение |
|---|---|---|
| 128 | Максимальная глубина рекурсии при кодировании |
| false | Флаг, указывающий, нужно ли обрезать таблицы с уровнем вложенности больше, чем |
| true | Флаг, указывающий, нужно ли включить кодирование чисел NaN и Inf |
| 14 | Точность чисел с плавающей запятой |
| true | Флаг, указывающий, будет ли сериализатор следовать полю метатаблицы __serialize |
| false | Флаг, указывающий, нужно ли использовать |
| false | Флаг, указывающий, нужно ли использовать NULL для нераспознанных типов |
| true | Флаг, указывающий, нужно ли обрабатывать разреженные массивы как отображения. Подробное описание см. ниже. |
| 2 | 1/ |
| 10 | Ограничение, гарантирующее, что небольшие Lua-массивы всегда кодируются как разреженные массивы (вместо генерации ошибки или кодирования как отображения) |
| true | Флаг, указывающий, нужно ли включить декодирование чисел NaN и Inf |
| true | Флаг, указывающий, нужно ли задавать метатаблицы для всех массивов и отображений |
| 128 | Максимальная глубина рекурсии при декодировании |
При кодировании JSON-кодировщик пытается классифицировать таблицу в одну из четырёх категорий:
- map (отображение) — хотя бы один индекс таблицы не является беззнаковым целым числом
- регулярный массив — все индексы массива доступны
- разреженный массив — отсутствует хотя бы один индекс массива
- чрезмерно разреженный массив — количество пропущенных значений превышает заданное отношение
Массив считается чрезмерно разреженным, если выполняются все следующие условия:
encode_sparse_ratio> 0max(table)>encode_sparse_safemax(table)>count(table)*encode_sparse_ratio
JSON-кодировщик никогда не сочтёт массив чрезмерно разреженным при
encode_sparse_ratio = 0. Ограничение encode_sparse_safe гарантирует,
что небольшие Lua-массивы всегда кодируются как разреженные массивы. По
умолчанию попытка закодировать чрезмерно разреженный массив приведёт к
ошибке. Если параметр encode_sparse_convert установлен в значение
true, чрезмерно разреженные массивы будут обрабатываться как
отображения.
Пример json.cfg() 1:
Следующий код закодирует 0/0 как NaN ("не число") и 1/0 как Inf ("бесконечность"), вместо возврата nil или сообщения об ошибке:
json = require('json')json.cfg{encode_invalid_numbers = true}x = 0/0y = 1/0json.encode({1, x, y, 2})
Результат запроса json.encode() будет следующим:
tarantool> json.encode({1, x, y, 2})---- '[1,nan,inf,2]'...
Пример json.cfg 2:
Чтобы избежать ошибок при попытке закодировать неизвестные типы данных, такие как userdata/cdata, можно использовать следующий код:
tarantool> httpc = require('http.client').new()---...tarantool> json.encode(httpc.curl)---- error: unsupported Lua type 'userdata'...tarantool> json.encode(httpc.curl, {encode_use_tostring=true})---- '"userdata: 0x010a4ef2a0"'...
Аналогичные параметры конфигурации существуют для MsgPack и YAML.
Значение, сопоставимое с нулевым значением "nil" в языке Lua, которое можно использовать в качестве объекта-заполнителя в кортеже.
Пример:
-- Когда полю Lua-таблицы присваивается nil, это поле -- nulltarantool> {nil, 'a', 'b'}---- - null- a- b...-- Когда полю Lua-таблицы присваивается json.NULL, это поле -- json.NULLtarantool> {json.NULL, 'a', 'b'}---- - null- a- b...-- Когда JSON-полю присваивается json.NULL, это поле -- nulltarantool> json.encode({field2 = json.NULL, field1 = 'a', field3 = 'c'})---- '{"field2":null,"field1":"a","field3":"c"}'...