JSON Pointer Operations for Structs¶
Glaze provides JSON Pointer (RFC 6901) operations that work directly with C++ structs and typed data. These operations provide patch-like functionality at compile time with full type safety.
For runtime JSON manipulation with full RFC 6902 JSON Patch support, see JSON Patch which works with
glz::generic.
Overview¶
| Operation | Description | Struct Support |
|---|---|---|
glz::get |
Read a value at a path | Yes |
glz::set |
Write a value at a path | Yes |
glz::seek |
Call a function on a value at a path | Yes |
glz::read_as_json |
Parse JSON into a specific path | Yes |
glz::write_at |
Write raw JSON at a specific path | Yes |
get - Read Values¶
get (reference)¶
Returns a reference wrapper to the value at the specified path:
struct Person {
std::string name;
int age;
};
Person p{"Alice", 30};
auto name = glz::get<std::string>(p, "/name");
if (name) {
// name->get() == "Alice"
name->get() = "Bob"; // Can modify through reference
}
auto age = glz::get<int>(p, "/age");
if (age) {
// age->get() == 30
}
get_if (pointer)¶
Returns a pointer to the value, or nullptr if not found or wrong type:
Person p{"Alice", 30};
if (auto* name = glz::get_if<std::string>(p, "/name")) {
// *name == "Alice"
}
// Returns nullptr for wrong type
auto* wrong = glz::get_if<int>(p, "/name"); // nullptr
get_value (copy)¶
Returns a copy of the value:
Person p{"Alice", 30};
auto age = glz::get_value<int>(p, "/age");
if (age) {
// *age == 30 (copy, not reference)
}
set - Write Values¶
Assigns a value at the specified path:
struct Config {
int timeout;
std::string host;
struct {
int port;
bool ssl;
} server;
};
Config cfg{30, "localhost", {8080, false}};
glz::set(cfg, "/timeout", 60);
glz::set(cfg, "/host", std::string("example.com"));
glz::set(cfg, "/server/port", 443);
glz::set(cfg, "/server/ssl", true);
set returns true if the assignment succeeded, false if the path doesn't exist or types are incompatible.
seek - Generic Access¶
Calls a lambda on the value at the specified path. Useful when you don't know the type at compile time:
struct Data {
int x;
double y;
std::string z;
};
Data d{1, 2.5, "hello"};
std::any result;
glz::seek([&](auto& value) {
result = value;
}, d, "/y");
// result contains 2.5
Nested Structures¶
All operations work with arbitrarily nested structures:
struct Inner {
int value;
};
struct Middle {
Inner inner;
std::vector<int> items;
};
struct Outer {
Middle middle;
std::map<std::string, int> scores;
};
Outer obj{{{{42}, {1, 2, 3}}, {{"math", 95}}}};
// Access nested struct
auto val = glz::get<int>(obj, "/middle/inner/value"); // 42
// Access vector element
auto item = glz::get<int>(obj, "/middle/items/1"); // 2
// Access map value
auto score = glz::get<int>(obj, "/scores/math"); // 95
// Set nested values
glz::set(obj, "/middle/inner/value", 100);
glz::set(obj, "/middle/items/0", 10);
Working with JSON Buffers¶
read_as_json¶
Parse JSON directly into a specific path within a struct:
struct Scene {
struct {
double x, y, z;
} position;
std::string name;
};
Scene scene{};
// Parse JSON into a specific location
glz::read_as_json(scene, "/position", R"({"x": 1.0, "y": 2.0, "z": 3.0})");
glz::read_as_json(scene, "/name", R"("Main Camera")");
get_as_json¶
Extract a typed value from a JSON buffer at a specific path:
std::string json = R"({"user": {"name": "Alice", "age": 30}})";
auto name = glz::get_as_json<std::string, "/user/name">(json);
// name == "Alice"
auto age = glz::get_as_json<int, "/user/age">(json);
// age == 30
get_sv_json¶
Get a std::string_view to the raw JSON at a path (no parsing):
std::string json = R"({"data": {"values": [1, 2, 3]}})";
auto view = glz::get_sv_json<"/data/values">(json);
// view == "[1, 2, 3]"
write_at¶
Replace JSON at a specific path within a buffer:
std::string json = R"({"action": "pending", "count": 0})";
glz::write_at<"/action">(R"("complete")", json);
glz::write_at<"/count">("42", json);
// json == {"action": "complete", "count": 42}
Comparison with JSON Patch¶
| Feature | Struct Operations | JSON Patch (glz::generic) |
|---|---|---|
| Type safety | Compile-time | Runtime |
| Add new keys | No (struct is fixed) | Yes |
| Remove keys | No (struct is fixed) | Yes |
| Replace values | Yes (glz::set) |
Yes |
| Move/Copy | No | Yes |
| Test operation | No | Yes |
| Batch operations | Manual loop | Atomic transaction |
When to Use Each¶
Use struct operations when: - You have a known schema at compile time - You need maximum performance - Type safety is important - Structure is fixed (no dynamic keys)
Use JSON Patch (glz::generic) when:
- Schema is unknown or dynamic
- You need full RFC 6902 compliance
- You need to add/remove keys at runtime
- You're processing patches from external sources
- You need atomic batch operations with rollback
Error Handling¶
Most operations return expected or bool to indicate success:
struct Data { int x; };
Data d{42};
// Path doesn't exist
auto result = glz::get<int>(d, "/nonexistent");
if (!result) {
// result.error().ec == glz::error_code::nonexistent_json_ptr
}
// Wrong type
auto wrong = glz::get<std::string>(d, "/x");
if (!wrong) {
// wrong.error().ec == glz::error_code::get_wrong_type
}
// set returns bool
bool ok = glz::set(d, "/x", 100); // true
bool fail = glz::set(d, "/y", 0); // false (path doesn't exist)
See Also¶
- JSON Pointer Syntax - Full JSON Pointer documentation
- JSON Patch - RFC 6902 JSON Patch for
glz::generic - Generic JSON - Working with dynamic JSON