Module json

Le module json convertit entre valeurs YScript et texte JSON : json.encode (valeur -> texte) et json.decode (texte -> valeur). Pas de dépendance sur io ou tout autre module : il fonctionne uniquement sur des chaînes en mémoire.

local json = require("json")

local text = json.encode({ name = "Yanos", age = 42 })
local data = json.decode(text)
print(data.name, data.age)

Vue d'ensemble

Fonction Description
json.encode(value [, indent]) Encode une valeur YScript en texte JSON
json.decode(str) Décode un texte JSON en valeur YScript

json.encode(value [, indent])

Encode value en texte JSON.

Correspondance des types

Valeur YScript JSON produit
nil null
true / false true / false
entier (ex. 42) nombre JSON entier (42)
flottant (ex. 1.5) nombre JSON avec un point/exposant, même s'il est mathématiquement entier (2.0, pas 2) — pour que le texte se re-décode bien en flottant
chaîne chaîne JSON, avec échappement des caractères spéciaux (", \, contrôles)
table dont les clés forment 1..n d'entiers consécutifs tableau JSON [...]
table (autre) objet JSON {...} — voir « Tables » ci-dessous
fonction, userdata, thread non encodable — voir « Valeurs non encodables » ci-dessous
print(json.encode(nil))              --> null
print(json.encode(42))               --> 42
print(json.encode(1.5))              --> 1.5
print(json.encode(2.0))              --> 2.0   (pas "2" : round-trip fidèle en flottant)
print(json.encode("hello \"world\""))--> "hello \"world\""

Un nombre flottant non fini (NaN, +inf, -inf) n'a pas de représentation JSON et lève une erreur script.

Tables

Une table est encodée comme un tableau JSON si et seulement si ses clés forment exactement la séquence 1, 2, ..., n (comme ipairs la parcourrait entièrement) ; sinon elle est encodée comme un objet JSON, avec les clés converties en chaînes :

print(json.encode({1, 2, 3}))                    --> [1,2,3]
print(json.encode({name = "Yanos", age = 30}))    --> {"name":"Yanos","age":30}
print(json.encode({[1] = "a", [3] = "c"}))        --> objet, pas tableau : {"1":"a","3":"c"}

Seules les clés de type chaîne ou nombre ont une représentation JSON ; une clé d'un autre type (table, booléen, fonction, ...) est silencieusement ignorée dans un objet.

Valeurs non encodables (fonctions, userdata, threads)

Une fonction, un userdata ou un thread n'a pas de représentation JSON :

print(json.encode(print))                    --> nil
print(json.encode({print}))                  --> [null]
print(json.encode({fn = print, kept = 1}))   --> {"kept":1}

Indentation (indent)

indent (argument 2, optionnel) contrôle la mise en forme :

Valeur Résultat
absent / false / nil compact, sans espace ni saut de ligne (défaut)
true indentation par défaut de 2 espaces par niveau
un nombre positif n indentation de n espaces par niveau
une chaîne utilisée telle quelle comme unité d'indentation par niveau
print(json.encode({1, 2}, true))
--> [
-->   1,
-->   2
--> ]

print(json.encode({1, 2}, 4))
--> [
-->     1,
-->     2
--> ]

print(json.encode({1, 2}, "\t"))
--> [
--> 	1,
--> 	2
--> ]

json.decode(str)

Décode le texte JSON str en valeur YScript et la retourne.

JSON Valeur YScript
null nil
true / false true / false
nombre sans ./e/E entier YScript
nombre avec ./e/E flottant YScript
chaîne chaîne (échappements standards \", \\, \/, \b, \f, \n, \r, \t, \uXXXX résolus)
objet {...} table avec clés chaînes
tableau [...] table avec clés entières 1..n
local data = json.decode('{"name":"Yanos","values":[1,2,3],"active":true,"note":null}')
print(data.name, data.values[1], data.active, data.note)
--> Yanos  1  true  nil

print(json.decode("42"), json.decode("-1.5"), json.decode("2e2"))
--> 42  -1.5  200

⚠️ Contrairement à json.encode, un texte JSON invalide fait lever une erreur script par json.decode (pas de nil, message) — capturez-la avec pcall si l'entrée n'est pas fiable :

local ok, result = pcall(json.decode, "{invalid}")
if not ok then
    print("JSON invalide : " .. result)
end

Notes de décodage :

Exemple complet

local json = require("json")

-- Encoder une structure imbriquée, lisible
local doc = {
    name = "mypackage",
    version = "1.0.0",
    tags = { "cli", "tool" },
    author = { name = "Yanos", email = "yanos@example.com" },
}
local text = json.encode(doc, true)
print(text)

-- Round-trip
local decoded = json.decode(text)
print(decoded.name, decoded.tags[1], decoded.author.name)

-- Entrée non fiable : capturer une erreur de décodage
local ok, result = pcall(json.decode, untrustedInput)
if ok then
    -- 'result' est la valeur décodée
else
    print("entrée invalide : " .. result)
end