#pragma once #include #include #include #include #include "weaseljson.h" inline WeaselJsonCallbacks printCallbacks() { WeaselJsonCallbacks result; result.on_begin_object = +[](void *) { puts("on_begin_object"); }; result.on_end_object = +[](void *) { puts("on_end_object"); }; result.on_begin_string = +[](void *) { puts("on_begin_string"); }; result.on_string_data = +[](void *, const char *buf, int len) { printf("on_string_data `%.*s`\n", len, buf); }; result.on_end_string = +[](void *) { puts("on_end_string"); }; result.on_begin_array = +[](void *) { puts("on_begin_array"); }; result.on_end_array = +[](void *) { puts("on_end_array"); }; result.on_begin_number = +[](void *) { puts("on_begin_number"); }; result.on_number_data = +[](void *, const char *buf, int len) { printf("on_number_data `%.*s`\n", len, buf); }; result.on_end_number = +[](void *) { puts("on_end_number"); }; result.on_true_literal = +[](void *) { puts("on_true_literal"); }; result.on_false_literal = +[](void *) { puts("on_false_literal"); }; result.on_null_literal = +[](void *) { puts("on_null_literal"); }; return result; } inline WeaselJsonCallbacks noopCallbacks() { WeaselJsonCallbacks result; result.on_begin_object = +[](void *) {}; result.on_end_object = +[](void *) {}; result.on_begin_string = +[](void *) {}; result.on_string_data = +[](void *, const char *buf, int len) {}; result.on_end_string = +[](void *) {}; result.on_begin_array = +[](void *) {}; result.on_end_array = +[](void *) {}; result.on_begin_number = +[](void *) {}; result.on_number_data = +[](void *, const char *buf, int len) {}; result.on_end_number = +[](void *) {}; result.on_true_literal = +[](void *) {}; result.on_false_literal = +[](void *) {}; result.on_null_literal = +[](void *) {}; return result; } struct SerializeState { bool isKey = false; struct Cursor { int64_t index; bool isObject; }; std::string result; void on_begin_value() { if (!stack.empty()) { auto &back = stack.back(); if (back.isObject && back.index % 2 == 0 && back.index > 0) { result.append(","); } if (back.isObject && back.index % 2 == 1 && back.index > 0) { result.append(":"); } if (!back.isObject && back.index > 0) { result.append(","); } ++back.index; } } std::vector stack; }; inline WeaselJsonCallbacks serializeCallbacks() { WeaselJsonCallbacks result; result.on_begin_object = +[](void *p) { auto *state = (SerializeState *)p; state->on_begin_value(); state->stack.push_back({0, true}); state->result.append("{"); }; result.on_end_object = +[](void *p) { auto *state = (SerializeState *)p; state->stack.pop_back(); state->result.append("}"); }; result.on_begin_string = +[](void *p) { auto *state = (SerializeState *)p; state->on_begin_value(); state->result.append("<"); }; result.on_string_data = +[](void *p, const char *buf, int len) { auto *state = (SerializeState *)p; state->result.append(std::string(buf, len)); }; result.on_end_string = +[](void *p) { auto *state = (SerializeState *)p; state->result.append(">"); }; result.on_begin_array = +[](void *p) { auto *state = (SerializeState *)p; state->on_begin_value(); state->stack.push_back({0, false}); state->result.append("["); }; result.on_end_array = +[](void *p) { auto *state = (SerializeState *)p; state->stack.pop_back(); state->result.append("]"); }; result.on_begin_number = +[](void *p) { auto *state = (SerializeState *)p; state->on_begin_value(); state->result.append("("); }; result.on_number_data = +[](void *p, const char *buf, int len) { auto *state = (SerializeState *)p; state->result.append(std::string(buf, len)); }; result.on_end_number = +[](void *p) { auto *state = (SerializeState *)p; state->result.append(")"); }; result.on_true_literal = +[](void *p) { auto *state = (SerializeState *)p; state->on_begin_value(); state->result.append("true"); }; result.on_false_literal = +[](void *p) { auto *state = (SerializeState *)p; state->on_begin_value(); state->result.append("false"); }; result.on_null_literal = +[](void *p) { auto *state = (SerializeState *)p; state->on_begin_value(); state->result.append("null"); }; return result; }