Add context to pointer results (yyjson_mut_get_pointern_ex)
I find it common to want to replace the value discovered by a call to yyjson_mut_get_pointer, however the current API provides no context about where in the document the match was found.
I propose a yyjson_mut_get_pointern_ex (which yyjson_mut_get_pointer would use) with something like:
yyjson_mut_val * yyjson_mut_get_pointern_ex(
const char *pointer,
size_t pointer_len,
yyjson_mut_val *container,
const char *key,
size_t *idx;
)
This would return the pointer as it does now, but would also populate container (if not NULL) with the yyjson_mut_val that contains the matching value. If container is a yyjson_mut_obj, it would populate key with the matching key. If container is a yyjson_mut_arr, it would populate idx. This would provide enough information to replace the returned value in its parent.
I'm happy to implement this one, but I'm hoping you have an idea for a better API.
Since the container here is implemented with a circular linked list, I thought it would be enough to return a previous node (previous value in array or previous key in object), for example:
yyjson_mut_val *yyjson_mut_get_pointer_ex(yyjson_mut_val *val,
const char *ptr,
size_t len,
yyjson_mut_val **ctn,
yyjson_mut_val **pre);
void yyjson_mut_replace_pointer_ex(yyjson_mut_val *ctn,
yyjson_mut_val *pre,
yyjson_mut_val *new_val);
void yyjson_mut_remove_pointer_ex(yyjson_mut_val *ctn,
yyjson_mut_val *pre);
The previous node can be used as a one-time token to replace or remove the matching node like this:
void yyjson_mut_replace_pointer_ex(yyjson_mut_val *ctn,
yyjson_mut_val *pre,
yyjson_mut_val *new_val) {
// check input...
if (yyjson_mut_is_arr(ctn)) {
yyjson_mut_val *old_val = pre->next;
if (ctn->uni.ptr == old_val) ctn->uni.ptr = new_val;
if (old_val->next == old_val) {
new_val->next = new_val;
} else {
new_val->next = old_val->next;
pre->next = new_val;
}
} else {
yyjson_mut_val *old_key = pre->next->next;
yyjson_mut_val *old_val = old_key->next;
new_val->next = old_val->next;
old_key->next = new_val;
}
}
Significantly simpler, I like it :+1:
The new functions have been added to the master branch.