Concatenate a path array (yyjson_val of strings) into a single * dotted QN string, optionally prefixed by `crate_qn`. */
| 41 | /* Concatenate a path array (yyjson_val of strings) into a single |
| 42 | * dotted QN string, optionally prefixed by `crate_qn`. */ |
| 43 | static const char* join_path(CBMArena* arena, yyjson_val* path_arr, |
| 44 | const char* crate_qn) { |
| 45 | if (!path_arr || !yyjson_is_arr(path_arr)) return NULL; |
| 46 | char buf[1024]; |
| 47 | int off = 0; |
| 48 | if (crate_qn && crate_qn[0]) { |
| 49 | off = snprintf(buf, sizeof(buf), "%s", crate_qn); |
| 50 | } |
| 51 | yyjson_val* part; |
| 52 | yyjson_arr_iter it; |
| 53 | yyjson_arr_iter_init(path_arr, &it); |
| 54 | bool first = true; |
| 55 | while ((part = yyjson_arr_iter_next(&it))) { |
| 56 | const char* s = yyjson_get_str(part); |
| 57 | if (!s) continue; |
| 58 | /* Skip the crate's own root segment if we already prefixed. */ |
| 59 | if (first && crate_qn && crate_qn[0] && strcmp(s, crate_qn) == 0) { |
| 60 | first = false; |
| 61 | continue; |
| 62 | } |
| 63 | if (off > 0 && off < (int)sizeof(buf) - 1) { |
| 64 | buf[off++] = '.'; |
| 65 | } |
| 66 | int n = snprintf(buf + off, sizeof(buf) - off, "%s", s); |
| 67 | if (n < 0) break; |
| 68 | off += n; |
| 69 | if (off >= (int)sizeof(buf) - 1) break; |
| 70 | first = false; |
| 71 | } |
| 72 | if (off <= 0) return NULL; |
| 73 | return cbm_arena_strndup(arena, buf, (size_t)off); |
| 74 | } |
| 75 | |
| 76 | /* Convert a rustdoc Type JSON value into a CBMType. Best-effort — |
| 77 | * rustdoc's Type union is large. We map: |
no test coverage detected