JR_OBJ
- Macro
- August 22, 2025
Table of Contents
JR_OBJ
JR_OBJ
Description
Read a JSON object using a custom field reader expression. The macro parses the object and invokes the provided code block for each key-value pair. If the key is not recognized or parsing fails, the value is skipped.
Parameters
Name | Direction | Description |
---|---|---|
si | in,out | Stream iterator to read from. |
Usage example (from documentation)
JR_OBJ(si, {
JR_STR_KV(si, "name", obj.name);
JR_INT_KV(si, "id", obj.id);
});
Success
Entire object read or skipped successfully
Failure
Logs error and restores si
on structural or read failure
Usage example (Cross-references)
- In
JSON.h:624
:
do { \
if (!StrCmpZstr(&key, (k))) { \
JR_OBJ(si, reader); \
} \
} while (0)
- In
MisraEnum.c:61
:
i64 last_value = 0;
JR_OBJ(json, {
JR_STR_KV(json, "name", enum_name);
JR_BOOL_KV(json, "to_from_str", to_from_str);
- In
MisraEnum.c:78
:
EnumEntry e = {0};
JR_OBJ(json, {
JR_STR_KV(json, "name", e.name);
JR_INT_KV(json, "value", e.value);
- In
MisraDoc.c:43
:
p.test_directories = VecInitT(p.test_directories); \
p.source_directories = VecInitT(p.source_directories); \
JR_OBJ(json, { \
JR_OBJ_KV(json, "project", { \
JR_STR_KV(json, "build_dir", p.build_dir); \
- In
Read.Simple.c:68
:
Str city = StrInit();
JR_OBJ(si, {
JR_STR_KV(si, "name", name);
JR_STR_KV(si, "city", city);
u32 year = 0;
JR_OBJ(si, {
JR_INT_KV(si, "count", count);
JR_FLT_KV(si, "score", score);
bool visible = true;
JR_OBJ(si, {
JR_BOOL_KV(si, "enabled", enabled);
JR_BOOL_KV(si, "visible", visible);
person.name = StrInit();
JR_OBJ(si, {
JR_INT_KV(si, "id", person.id);
JR_STR_KV(si, "name", person.name);
config.log_level = StrInit();
JR_OBJ(si, {
JR_BOOL_KV(si, "debug_mode", config.debug_mode);
JR_INT_KV(si, "timeout", config.timeout);
Vec(Str) languages = VecInitWithDeepCopy(NULL, StrDeinit);
JR_OBJ(si, {
JR_ARR_KV(si, "languages", {
Str lang = StrInit();
};
JR_OBJ(si, {
JR_OBJ_KV(si, "user", {
JR_STR_KV(si, "name", data.user.name);
product.tags = VecInitWithDeepCopyT(product.tags, NULL, StrDeinit);
JR_OBJ(si, {
JR_INT_KV(si, "id", product.id);
JR_STR_KV(si, "name", product.name);
obj1.found_anything = false; // Start as true to test it gets properly handled
JR_OBJ(si1, {
obj1.found_anything = true; // This should never execute for empty object
});
obj2.found_anything = false;
JR_OBJ(si2, { obj2.found_anything = true; });
if (!obj2.found_anything) { // Should still be true for empty object
Vec(i32) items = VecInit();
JR_OBJ(si1, {
JR_ARR_KV(si1, "items", {
i32 value = 0;
Vec(Str) data = VecInitWithDeepCopy(NULL, StrDeinit);
JR_OBJ(si2, {
JR_ARR_KV(si2, "data", {
Str value = StrInit();
} obj = {StrInit(), StrInit()};
JR_OBJ(si, {
JR_STR_KV(si, "name", obj.name);
JR_STR_KV(si, "description", obj.description);
} obj = {0};
JR_OBJ(si, {
JR_INT_KV(si, "temp", obj.temp);
JR_FLT_KV(si, "balance", obj.balance);
} obj = {0};
JR_OBJ(si, {
JR_INT_KV(si, "big_int", obj.big_int);
JR_FLT_KV(si, "big_float", obj.big_float);
} obj = {999, 999.0, true}; // Initialize with non-zero values
JR_OBJ(si, {
JR_INT_KV(si, "int_zero", obj.int_zero);
JR_FLT_KV(si, "float_zero", obj.float_zero);
} obj = {StrInit(), StrInit(), StrInit()};
JR_OBJ(si, {
JR_STR_KV(si, "path", obj.path);
JR_STR_KV(si, "message", obj.message);
} obj = {StrInit(), StrInit(), StrInit(), StrInit()};
JR_OBJ(si, {
JR_STR_KV(si, "escaped", obj.escaped);
JR_STR_KV(si, "backslash", obj.backslash);
} obj = {StrInit(), 0, false};
JR_OBJ(si, {
JR_STR_KV(si, "name", obj.name);
JR_INT_KV(si, "value", obj.value);
} obj = {false, false, false, false};
JR_OBJ(si, {
JR_OBJ_KV(si, "outer", { obj.found_outer = true; });
JR_ARR_KV(si, "list", {
} obj = {0, VecInit()};
JR_OBJ(si, {
JR_OBJ_KV(
si,
} obj = {0};
JR_OBJ(si, {
JR_INT_KV(si, "max_int", obj.max_int);
JR_INT_KV(si, "min_int", obj.min_int);
} obj = {0};
JR_OBJ(si, {
JR_FLT_KV(si, "tiny", obj.tiny);
JR_FLT_KV(si, "huge", obj.huge);
- In
RoundTrip.c:118
:
StrIter si = StrIterFromStr(json);
JR_OBJ(si, {
JR_INT_KV(si, "count", parsed.count);
JR_FLT_KV(si, "temperature", parsed.temperature);
- In
RoundTrip.c:194
:
StrIter si = StrIterFromStr(json);
JR_OBJ(si, {
JR_INT_KV(si, "big_int", parsed.big_int);
JR_INT_KV(si, "negative_int", parsed.negative_int);
- In
RoundTrip.c:258
:
StrIter si = StrIterFromStr(json);
JR_OBJ(si, {
JR_BOOL_KV(si, "flag1", parsed.flag1);
JR_BOOL_KV(si, "flag2", parsed.flag2);
- In
RoundTrip.c:315
:
StrIter si = StrIterFromStr(json);
JR_OBJ(si, {
JR_STR_KV(si, "empty", parsed.empty);
JR_STR_KV(si, "simple", parsed.simple);
- In
RoundTrip.c:384
:
StrIter si = StrIterFromStr(json);
JR_OBJ(si, {
JR_ARR_KV(si, "numbers", {
i32 num = 0;
- In
RoundTrip.c:473
:
StrIter si = StrIterFromStr(json);
JR_OBJ(si, {
JR_OBJ_KV(si, "user", {
JR_INT_KV(si, "id", parsed_person.id);
- In
RoundTrip.c:569
:
StrIter si = StrIterFromStr(json);
JR_OBJ(si, {
JR_OBJ_KV(si, "user", {
JR_INT_KV(si, "id", parsed.user.id);
- In
RoundTrip.c:674
:
StrIter si = StrIterFromStr(json);
JR_OBJ(si, {
JR_STR_KV(si, "empty_string", parsed_str);
JR_ARR_KV(si, "empty_numbers", {
- In
RoundTrip.c:754
:
StrIter si = StrIterFromStr(json);
JR_OBJ(si, {
JR_INT_KV(si, "max_int", parsed.max_int);
JR_INT_KV(si, "min_int", parsed.min_int);
} data = {0, StrInit(), false, 0.0};
JR_OBJ(si, {
JR_INT_KV(si, "id", data.id);
JR_STR_KV(si, "name", data.name);
};
JR_OBJ(si, {
JR_OBJ_KV(si, "user", {
JR_INT_KV(si, "id", data.user.id);
};
JR_OBJ(si, {
JR_OBJ_KV(si, "company", {
JR_OBJ_KV(si, "departments", {
Symbols symbols = VecInitWithDeepCopy(NULL, AnnSymbolDeinit);
JR_OBJ(si, {
JR_OBJ_KV(si, "functions", {
// First level: source function ID from key
// First level: source function ID from key
u64 source_function_id = strtoull(key.data, NULL, 10);
JR_OBJ(si, {
// Second level: target function ID from key
u64 target_function_id = strtoull(key.data, NULL, 10);
sym.target_function_id = target_function_id;
JR_OBJ(si, {
JR_FLT_KV(si, "distance", sym.distance);
JR_STR_KV(si, "name", sym.function_name);
ApiResponse response = {false, StrInit(), VecInitWithDeepCopy(NULL, AnnSymbolDeinit)};
JR_OBJ(si, {
JR_BOOL_KV(si, "status", response.status);
JR_STR_KV(si, "message", response.message);
JR_OBJ_KV(si, "data", {
u64 source_function_id = strtoull(key.data, NULL, 10);
JR_OBJ(si, {
// Properly initialize all Str fields
AnnSymbol sym = {0};
sym.target_function_id = strtoull(key.data, NULL, 10);
JR_OBJ(si, {
JR_FLT_KV(si, "distance", sym.distance);
JR_INT_KV(si, "nearest_neighbor_analysis_id", sym.analysis_id);
info.name = StrInit();
JR_OBJ(si, {
JR_INT_KV(si, "id", info.id);
JR_STR_KV(si, "name", info.name);
info.name = StrInit();
JR_OBJ(si, {
JR_INT_KV(si, "id", info.id);
JR_STR_KV(si, "name", info.name);
result.owned_by = StrInit();
JR_OBJ(si, {
JR_INT_KV(si, "binary_id", result.binary_id);
JR_STR_KV(si, "binary_name", result.binary_name);
printf("[DEBUG] About to parse JSON...\n");
JR_OBJ(si, {
JR_BOOL_KV(si, "status", response.status);
JR_STR_KV(si, "message", response.message);
u64 source_function_id = strtoull(key.data, NULL, 10);
printf("[DEBUG] Source function ID from key: %llu\n", source_function_id);
JR_OBJ(si, {
// Properly initialize all Str fields
AnnSymbol sym = {0};
printf("[DEBUG] Target function ID from key: %llu\n", sym.target_function_id);
JR_OBJ(si, {
JR_FLT_KV(si, "distance", sym.distance);
JR_INT_KV(si, "nearest_neighbor_analysis_id", sym.analysis_id);
printf("[DEBUG] About to parse JSON...\n");
JR_OBJ(si, {
JR_BOOL_KV(si, "status", response.status);
JR_STR_KV(si, "message", response.message);
u64 source_function_id = strtoull(key.data, NULL, 10);
printf("[DEBUG] Source function ID from key: %llu\n", source_function_id);
JR_OBJ(si, {
// Properly initialize all Str fields
AnnSymbol sym = {0};
printf("[DEBUG] Target function ID from key: %llu\n", sym.target_function_id);
JR_OBJ(si, {
JR_FLT_KV(si, "distance", sym.distance);
JR_INT_KV(si, "nearest_neighbor_analysis_id", sym.analysis_id);