JSON Skill
JSON5/JSON6 parsing, path queries, tree manipulation, iteration, and serialization.
Invoke with: /json
Key APIs
c
/* Parsing */
Json *jsonParse(cchar *text, int flags);
Json *jsonParseFile(cchar *path, char **errorMsg, int flags);
Json *jsonAlloc(void);
/* Querying -- nid is parent node ID, use 0 for root */
cchar *jsonGet(Json *json, int nid, cchar *key, cchar *defaultValue);
bool jsonGetBool(Json *json, int nid, cchar *key, bool defaultValue);
ssize jsonGetLength(Json *json, int nid, cchar *key);
/* Modification */
int jsonSet(Json *json, int nid, cchar *key, cchar *value, int type);
int jsonSetString(Json *json, int nid, cchar *key, cchar *value);
int jsonSetNum(Json *json, int nid, cchar *key, int64 value);
int jsonSetBool(Json *json, int nid, cchar *key, bool value);
int jsonSetJsonFmt(Json *json, int nid, cchar *key, cchar *fmt, ...);
/* Serialization */
char *jsonToString(const Json *json, int nid, cchar *key, int flags);
cchar *jsonString(const Json *json, int flags);
/* Lifecycle */
void jsonFree(Json *json);Parse and Query
c
Json *json;
cchar *name;
json = jsonParse(text, 0);
name = jsonGet(json, 0, "users.0.name", NULL);
if (name) {
rInfo("app", "Name: %s", name);
}
jsonFree(json);Dot-notation paths index into nested objects and arrays: "config.database.path", "items.0.name".
Building JSON Objects
c
Json *request = jsonAlloc();
jsonSetString(request, 0, "model", "gpt-4o-mini");
jsonSetString(request, 0, "input", userInput);
jsonSetNum(request, 0, "max_tokens", 1000);
jsonSetBool(request, 0, "stream", 0);
jsonFree(request);SDEF and SFMT Macros
SDEF(...) concatenates literal strings at compile time for multi-line JSON5 templates:
c
cchar *template = SDEF({
model: 'gpt-4o',
input: 'Hello',
});SFMT(buf, fmt, ...) formats a string into a stack buffer:
c
char buf[1024];
Json *json = jsonParse(SFMT(buf, SDEF({
model: '%s',
input: '%s',
}), model, input), 0);Iterating Arrays
c
/* By index */
ssize count = jsonGetLength(json, 0, "items");
for (int i = 0; i < count; i++) {
cchar *name = jsonGet(json, 0, sfmt("items.%d.name", i), NULL);
}
/* With ITERATE_JSON_KEY (preferred) */
JsonNode *child;
int nid;
for (ITERATE_JSON_KEY(json, 0, "items", child, nid)) {
cchar *name = jsonGet(json, nid, "name", NULL);
}Memory Ownership Rules
jsonGet()returns a pointer into the tree — invalid afterjsonFree()or tree modification.jsonToString()allocates a new string — caller mustrFree().jsonAlloc()andjsonParse()allocate trees — caller mustjsonFree().- Do NOT modify the tree during iteration.
