1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
# JMESPath Support
[JMESPath](https://jmespath.org/tutorial.html) is a query language for JSON.
Glaze currently has limited support for partial reading with JMESPath. Broader support will be added in the future.
- Compile time evaluated JMESPath expressions offer excellent performance.
Example:
```c++
struct Person
{
std::string first_name{};
std::string last_name{};
uint16_t age{};
};
struct Family
{
Person father{};
Person mother{};
std::vector<Person> children{};
};
struct Home
{
Family family{};
std::string address{};
};
suite jmespath_read_at_tests = [] {
"compile-time read_jmespath"_test = [] {
Home home{.family = {.father = {"Gilbert", "Fox", 28},
.mother = {"Anne", "Fox", 30},
.children = {{"Lilly"}, {"Vincent"}}}};
std::string buffer{};
expect(not glz::write_json(home, buffer));
std::string first_name{};
auto ec = glz::read_jmespath<"family.father.first_name">(first_name, buffer);
expect(not ec) << glz::format_error(ec, buffer);
expect(first_name == "Gilbert");
Person child{};
expect(not glz::read_jmespath<"family.children[0]">(child, buffer));
expect(child.first_name == "Lilly");
expect(not glz::read_jmespath<"family.children[1]">(child, buffer));
expect(child.first_name == "Vincent");
};
"run-time read_jmespath"_test = [] {
Home home{.family = {.father = {"Gilbert", "Fox", 28},
.mother = {"Anne", "Fox", 30},
.children = {{"Lilly"}, {"Vincent"}}}};
std::string buffer{};
expect(not glz::write_json(home, buffer));
std::string first_name{};
auto ec = glz::read_jmespath("family.father.first_name", first_name, buffer);
expect(not ec) << glz::format_error(ec, buffer);
expect(first_name == "Gilbert");
Person child{};
expect(not glz::read_jmespath("family.children[0]", child, buffer));
expect(child.first_name == "Lilly");
expect(not glz::read_jmespath("family.children[1]", child, buffer));
expect(child.first_name == "Vincent");
};
};
```
## Run-time Expressions
It can be expensive to tokenize at runtime. The runtime version of `glz::read_jmespath` takes in a `const glz::jmespath_expression&`. This allows expressions to be pre-computed, reused, and cached for better runtime performance.
```c++
Person child{};
// A runtime expression can be pre-computed and saved for more efficient lookups
glz::jmespath_expression expression{"family.children[0]"};
expect(not glz::read_jmespath(expression, child, buffer));
expect(child.first_name == "Lilly");
```
Note that this still works:
```c++
expect(not glz::read_jmespath("family.children[0]", child, buffer));
```
## Slices
```c++
suite jmespath_slice_tests = [] {
"slice compile-time"_test = [] {
std::vector<int> data{0,1,2,3,4,5,6,7,8,9};
std::string buffer{};
expect(not glz::write_json(data, buffer));
std::vector<int> slice{};
expect(not glz::read_jmespath<"[0:5]">(slice, buffer));
expect(slice.size() == 5);
expect(slice[0] == 0);
expect(slice[1] == 1);
expect(slice[2] == 2);
expect(slice[3] == 3);
expect(slice[4] == 4);
};
"slice run-time"_test = [] {
std::vector<int> data{0,1,2,3,4,5,6,7,8,9};
std::string buffer{};
expect(not glz::write_json(data, buffer));
std::vector<int> slice{};
expect(not glz::read_jmespath("[0:5]", slice, buffer));
expect(slice.size() == 5);
expect(slice[0] == 0);
expect(slice[1] == 1);
expect(slice[2] == 2);
expect(slice[3] == 3);
expect(slice[4] == 4);
};
"slice compile-time multi-bracket"_test = [] {
std::vector<std::vector<int>> data{{1,2},{3,4,5},{6,7}};
std::string buffer{};
expect(not glz::write_json(data, buffer));
int v{};
expect(not glz::read_jmespath<"[1][2]">(v, buffer));
expect(v == 5);
};
"slice run-time multi-bracket"_test = [] {
std::vector<std::vector<int>> data{{1,2},{3,4,5},{6,7}};
std::string buffer{};
expect(not glz::write_json(data, buffer));
int v{};
expect(not glz::read_jmespath("[1][2]", v, buffer));
expect(v == 5);
};
};
```
|