Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation for arrays of objects #52

Open
cesss opened this issue Oct 24, 2021 · 5 comments
Open

Documentation for arrays of objects #52

cesss opened this issue Oct 24, 2021 · 5 comments
Labels
documentation Improvements or additions to documentation

Comments

@cesss
Copy link

cesss commented Oct 24, 2021

Hi!

Your library is great! But one thing I couldn't find is how to serialize and deserialize arrays of objects, as well as nested objects. I saw that you have a couple of closed tickets regarding how to work with arrays of objects, so I believe that explaining it in the documentation will help a lot.

My main use for this library would be to dump arrays of C structs (and sometimes a struct can have another array of structs nested inside it)... so documentation about this would be very welcome!

@ibireme
Copy link
Owner

ibireme commented Oct 25, 2021

Thanks. I will add more documentation and demos later.

@ibireme ibireme added the documentation Improvements or additions to documentation label Oct 25, 2021
@kay54068
Copy link

hi,

I also have this need. have Do you have any updates?

@VaslD
Copy link

VaslD commented Jul 10, 2023

I use YYJSON in a Swift project, and this is the minimal code to serialize to (i.e. create, or fill) a yyjson_mut_doc. It's in Swift but should be quite comprehensible to C++ developers:

func encode(in document: UnsafeMutablePointer<yyjson_mut_doc>) -> UnsafeMutablePointer<yyjson_mut_val> {
    switch self {
    case .empty:
        return yyjson_mut_null(document)!
    case let .boolean(bool):
        return yyjson_mut_bool(document, bool)!
    case let .string(string):
        return string.withCString {
            yyjson_mut_strcpy(document, $0)!
        }
    case let .number(decimal):
        return (decimal as NSDecimalNumber).stringValue.withCString {
            yyjson_mut_rawcpy(document, $0)!
        }
    case let .array(array):
        let container = yyjson_mut_arr(document)
        for value in array {
            yyjson_mut_arr_append(container, value.encode(in: document))
        }
        return container!
    case let .dictionary(dictionary):
        let container = yyjson_mut_obj(document)
        for (key, value) in dictionary.sorted(by: { $0.key < $1.key }) {
            yyjson_mut_obj_add(container, key.withCString {
                yyjson_mut_strcpy(document, $0)!
            }, value.encode(in: document))
        }
        return container!
    }
}

Basically you need 3 things to work with arrays (of objects) and objects:

  1. A yyjson_mut_doc to allocate memory for new values, which is the input parameter of the function above.
  2. A newly allocated yyjson_mut_arr or yyjson_mut_obj as a container, as seen in the two container statements.
  3. A yyjson_mut_val (or yyjson_val), either allocated, converted from your C type(s), or obtained somewhere else, to put into the container, which is the output of the function above.

The function above calls itself recursively to process elements in arrays and objects.

@VaslD
Copy link

VaslD commented Jul 10, 2023

Deserialization is just reversing the input/output of the function:

(Assuming you're switching on the type of a yyjson_val)

case YYJSON_TYPE_ARR:
    var array = [JSON]()
    array.reserveCapacity(unsafe_yyjson_get_len(pointer))
    var iterator = yyjson_arr_iter()
    yyjson_arr_iter_init(pointer, &iterator)
    while let value = yyjson_arr_iter_next(&iterator) {
        array.append(JSON(value))
    }
    self = .array(array)

case YYJSON_TYPE_OBJ:
    var dictionary = [String: JSON](minimumCapacity: unsafe_yyjson_get_len(pointer))
    var iterator = yyjson_obj_iter()
    yyjson_obj_iter_init(pointer, &iterator)
    while let pair = yyjson_obj_iter_next(&iterator) {
        let key = String(cString: unsafe_yyjson_get_str(pair))
        let value = JSON(yyjson_obj_iter_get_val(pair)!)
        dictionary[key] = value
    }
    self = .dictionary(dictionary)

Sorry, still in Swift. The while let syntax checks and breaks the loop if return is null.

@Diego-Hernandez-Moodys
Copy link

Diego-Hernandez-Moodys commented Mar 18, 2024

Let's build the following json

{
    "collection": "embedded_movies",
    "steps": [
        {
            "search": {
                "index": "string",
                "queryVector": [0.0, 0.0, 0.0],
                "limit": 10,
            }
        },
        {
            "output": {
                "_id": 1,
                "score": { "meta": "vectorSearchScore" }
            }
        }
    ]
}
double* vector = malloc( 3 * sizeof(double) );
for (int i = 0; i < 3; i++)
{
    vector[i] = 0.0;
}
int size_vector = 3;
const* collection = "embedded_movies";

// Allocate
yyjson_mut_doc *doc = yyjson_mut_doc_new(NULL);
yyjson_mut_val *root = yyjson_mut_obj(doc);
yyjson_mut_val *root_array = yyjson_mut_arr(doc);

yyjson_mut_val *search = yyjson_mut_obj(doc);
yyjson_mut_val *search_body = yyjson_mut_obj(doc);
yyjson_mut_val *embedding_vector = yyjson_mut_arr_with_double(doc, vector, size_vector);

yyjson_mut_val *output = yyjson_mut_obj(doc);
yyjson_mut_val *output_body = yyjson_mut_obj(doc);
yyjson_mut_val *meta = yyjson_mut_obj(doc);

// Use
yyjson_mut_obj_add_str(doc, root, "collection", collection);

// Build the { search: {} } portion
yyjson_mut_obj_add_val(doc, search, "search", search_body);
yyjson_mut_obj_add_str(doc, search_body, "index", "string");
yyjson_mut_obj_add_int(doc, search_body, "limit", 10);
yyjson_mut_obj_add_val(doc, search_body, "queryVector", embedding_vector);

// Build the { output: {} } portion
yyjson_mut_obj_add_val(doc, output, "output", output_body);
yyjson_mut_obj_add_int(doc, output_body, "_id", 1);
yyjson_mut_obj_add_val(doc, output_body, "score", meta);
yyjson_mut_obj_add_str(doc, meta, "meta", "vectorSearchScore");

// Build the [ search, output ]
yyjson_mut_arr_append(root_array, search);
yyjson_mut_arr_append(root_array, output);

yyjson_mut_obj_add_val(doc, root, "steps", root_array);
yyjson_mut_doc_set_root(doc, root);

// mut_doc -> imutable doc
yyjson_doc *out = yyjson_mut_doc_imut_copy(doc, NULL);

// Free
yyjson_mut_doc_free(doc);
free(vector);
yyjson_doc_free(out);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

5 participants