| 195 | } |
| 196 | |
| 197 | int cbm_rust_rustdoc_ingest(CBMTypeRegistry* reg, CBMArena* arena, |
| 198 | const char* json, int json_len, const char* crate_qn) { |
| 199 | if (!reg || !arena || !json) return 0; |
| 200 | yyjson_doc* doc = yyjson_read(json, (size_t)(json_len > 0 ? json_len : strlen(json)), 0); |
| 201 | if (!doc) return 0; |
| 202 | yyjson_val* root = yyjson_doc_get_root(doc); |
| 203 | if (!yyjson_is_obj(root)) { yyjson_doc_free(doc); return 0; } |
| 204 | |
| 205 | yyjson_val* index = yyjson_obj_get(root, "index"); |
| 206 | yyjson_val* paths = yyjson_obj_get(root, "paths"); |
| 207 | if (!index || !paths) { yyjson_doc_free(doc); return 0; } |
| 208 | |
| 209 | int count = 0; |
| 210 | yyjson_obj_iter it; |
| 211 | yyjson_obj_iter_init(index, &it); |
| 212 | yyjson_val* key; |
| 213 | while ((key = yyjson_obj_iter_next(&it))) { |
| 214 | const char* item_id = yyjson_get_str(key); |
| 215 | if (!item_id) continue; |
| 216 | yyjson_val* item = yyjson_obj_iter_get_val(key); |
| 217 | if (!item || !yyjson_is_obj(item)) continue; |
| 218 | |
| 219 | yyjson_val* name = yyjson_obj_get(item, "name"); |
| 220 | const char* short_name = yyjson_get_str(name); |
| 221 | if (!short_name) continue; |
| 222 | |
| 223 | yyjson_val* inner = yyjson_obj_get(item, "inner"); |
| 224 | if (!inner || !yyjson_is_obj(inner)) continue; |
| 225 | |
| 226 | /* Look up the fully-qualified path. */ |
| 227 | yyjson_val* path_entry = yyjson_obj_get(paths, item_id); |
| 228 | const char* qn = NULL; |
| 229 | const char* kind = NULL; |
| 230 | if (path_entry && yyjson_is_obj(path_entry)) { |
| 231 | qn = join_path(arena, yyjson_obj_get(path_entry, "path"), crate_qn); |
| 232 | yyjson_val* k = yyjson_obj_get(path_entry, "kind"); |
| 233 | kind = yyjson_get_str(k); |
| 234 | } |
| 235 | if (!qn) { |
| 236 | /* Methods/impl-items don't have entries in `paths`; we still |
| 237 | * register them by name + receiver derived from the parent. */ |
| 238 | } |
| 239 | |
| 240 | /* Dispatch on the rustdoc kind. */ |
| 241 | if (kind && (strcmp(kind, "struct") == 0 || |
| 242 | strcmp(kind, "enum") == 0 || |
| 243 | strcmp(kind, "union") == 0)) { |
| 244 | CBMRegisteredType rt; |
| 245 | memset(&rt, 0, sizeof(rt)); |
| 246 | rt.qualified_name = qn; |
| 247 | rt.short_name = cbm_arena_strdup(arena, short_name); |
| 248 | cbm_registry_add_type(reg, rt); |
| 249 | count++; |
| 250 | } else if (kind && strcmp(kind, "trait") == 0) { |
| 251 | CBMRegisteredType rt; |
| 252 | memset(&rt, 0, sizeof(rt)); |
| 253 | rt.qualified_name = qn; |
| 254 | rt.short_name = cbm_arena_strdup(arena, short_name); |
no test coverage detected