Skip to content

# 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

    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

    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);