File: unknown-keys.md

package info (click to toggle)
glaze 6.5.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 7,948 kB
  • sloc: cpp: 121,839; sh: 99; ansic: 26; makefile: 13
file content (97 lines) | stat: -rw-r--r-- 2,524 bytes parent folder | download
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
# Unknown Keys

Sometimes you don't know in advance all the keys of your objects. By default, glaze will error on unknown keys.
If you set the compile time option `error_on_unknown_keys = false`, the behavior will change to skip the unknown keys.

Furthermore it is possible to customize the handling of object unknown keys at read and/or write time by defining `unknown_read` and `unknown_write` members of meta class as pointer to member or pointer to method.

Note : `unknown_write` is using `glz::merge` internally so unknown keys will be written at the end of object.

## Example

```c++
struct my_struct
{
  std::string hello;
  std::string zzz;
  std::map<glz::sv, glz::raw_json> extra; // store key/raw_json in extra map

  // with methods
  // void my_unknown_read(const glz::sv& key, const glz::raw_json& value) { 
  //     extra[key] = value;
  // };
  // std::map<glz::sv, glz::raw_json> my_unknown_write() const {
  //    return extra;
  // }

};

template <>
struct glz::meta<my_struct> {
   using T = my_struct;
   static constexpr auto value = object(
      "hello", &T::hello,
      "zzz", &T::zzz
   );
   
   // with members
   static constexpr auto unknown_write{&T::extra};
   static constexpr auto unknown_read{&T::extra};
   // with methods
   // static constexpr auto unknown_write{&T::my_unknown_write};
   // static constexpr auto unknown_read{&T::my_unknown_read};

};

// usage
std::string buffer = R"({"hello":"Hello World!","lang":"en","zzz":"zzz"})";
my_struct s{};

// decodes and retains extra unknown fields (lang) in extra map
glz::context ctx{};
glz::read<glz::opts{.error_on_unknown_keys = false}>(s, buffer, ctx);

// update
s.hello = "Hi !"

// encodes output string
std::string out{};
glz::write_json(s, out);

// out ==  {"hello":"Hi !","zzz":"zzz","lang":"en"}
```

## Example 2 : Known extra type

If the type of extra keys is known, this would work

```c++
struct my_struct
{
  std::string infinite;
  int zero;
  std::map<glz::sv, int> numbers;
};

template <>
struct glz::meta<my_struct> {
   using T = my_struct;
   static constexpr auto value = object(
      "infinite", &T::infinite,
      "zero", &T::zero
   );
   
   static constexpr auto unknown_read{&T::numbers};
};

// usage
// note extra keys (one, two) are of type int
std::string buffer = R"({"inf":"infinite","zero":0,"one":1,"two":2})";
my_struct s{};

// decodes and retains extra unknown fields (lang) in extra map
glz::context ctx{};
glz::read<glz::opts{.error_on_unknown_keys = false}>(s, buffer, ctx);
```