How to read portion object from unknown JSON string? #151
-
Hi I am reading through the README, however, I do not find an official way to read portion object from JSON string. The The common use case is to implement a API, we need to decide the message type, and then deserialize, for example {
"action": "PUT",
"data": {
"x": 100,
"y": 200
}
} Expected way std::string action = glz::read_json_whatever<std::string>("/path/to/action", buffer);
if (action == "DELETE") {
// Now we know the message type
auto bomb = glz::read_json<bomb_t>(buffer);
} Workaround (simdjson) Using the #include <iostream>
#include "simdjson.h"
using namespace simdjson;
int main(void) {
ondemand::parser parser;
std::string_view action;
std::string buffer = R"( { "action": "GET", "data": { "x": 10, "y": 200 }})";
auto json = padded_string(buffer);
auto request = parser.iterate(json);
auto error = request.at_pointer("/action").get_string().get(action);
if (action == "GET") {
printf("TODO: deserialize with glaze as GET\n");
}
return 0;
} |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 1 reply
-
Thanks for the thoughtful reply, BTW I never know there's a glz::json_t variant. Since I am reluctant to integrate extra JSON libraries, So I will go with string pattern matching. Different JSON messages are so common in a websocket stream, so we have to decide the message types and deserialize them. {"action":"subscribe", "symbols": ["BTCUSDT", "ETHUSDT"]}
{"action":"trade", "data": {"symbol": "ETHUSDT", "price": "123.4","volume":100}} Substring matching auto buffer = "{...}";
if (buffer.starts_with("{\"action\":\"subscribe\"")) {
auto subscribe = glz::read_json<subscribe_t>(buffer);
} Thanks anyway, I will stay tune to the project. |
Beta Was this translation helpful? Give feedback.
-
@sweihub Your example problem can now be solved as follows: struct xy_t {
int x{};
int y{};
};
template <>
struct glz::meta<xy_t> {
using T = xy_t;
static constexpr auto value = object("x", &T::x, "y", &T::y);
};
struct bomb_t {
xy_t data{};
};
template <>
struct glz::meta<bomb_t> {
using T = bomb_t;
static constexpr auto value = object("action", skip{}, "data", &T::data);
}; In use: std::string buffer = R"( { "action": "DELETE", "data": { "x": 10, "y": 200 }})";
auto action = glz::get_sv_json<"/action">(buffer);
expect(action == R"("DELETE")");
if (action == R"("DELETE")") {
auto bomb = glz::read_json<bomb_t>(buffer);
expect(bomb.data.x == 10);
expect(bomb.data.y == 200);
} Notice that
if (action == "DELETE") I hope all this makes sense, feel free to ask questions. We'll be adding documentation for these functions in the future. |
Beta Was this translation helpful? Give feedback.
-
#I never thought that you guys move so quickly, that really makes sense, I don't need an extra JSON library now , just stick to Discuss
I agree with performance considerations, void main()
{
auto action = R"("DELETE")";
auto sv = std::string_view(action + 1, strlen(action) - 2);
assert(sv == "DELETE");
std::cout << sv << std::endl;
}
Would you consider a more general name for Thanks! |
Beta Was this translation helpful? Give feedback.
-
I just tested the new feature struct xy_t {
int x{};
int y{};
};
template <> struct glz::meta<xy_t> {
using T = xy_t;
static constexpr auto value = object("x", &T::x, "y", &T::y);
};
struct bomb_t {
xy_t data{};
int weight = 1000;
};
template <> struct glz::meta<bomb_t> {
using T = bomb_t;
static constexpr auto value = object("weight", &T::weight, "data", &T::data, "action", skip{});
};
void test_glaze() {
std::string buffer = R"({"weight": 3000, "data": { "x": 10, "y": 200 }, "action": "DESTROY"})";
auto action = glz::get_as_json<std::string, "/action">(buffer);
assert(action == "DESTROY");
if (action == "DESTROY") {
auto bomb = glz::read_json<bomb_t>(buffer);
assert(bomb.data.x == 10);
assert(bomb.data.y == 200);
std::cout << "bomb.weight: " << bomb.weight << std::endl;
}
} |
Beta Was this translation helpful? Give feedback.
@sweihub
#150 has been merged with main. This adds the ability to generally parse a targeted value.
Your example problem can now be solved as follows:
In use: