getml / reflect-cpp

A C++20 library for fast serialization, deserialization and validation using reflection. Supports JSON, BSON, CBOR, flexbuffers, msgpack, TOML, XML, YAML / msgpack.org[C++20]
https://getml.github.io/reflect-cpp/
MIT License
982 stars 85 forks source link

Json null support ? #100

Closed BestITUserEUW closed 4 months ago

BestITUserEUW commented 4 months ago

Hey,

Does this library support null ? One of my services i use requires properties to be set to null in some cases.

Example: { "property": null }

Something like std::optional but if value is nullptr or NULL it has the value null in the json string. As defined in: json.org

liuzicheng1987 commented 4 months ago

@BestITUserEUW The answer is yes and no.

The null value has been added to the JSON standard a bit later, so some JSON parsers won't be able to handle it.

Therefore, when you write values that are null, the corresponding field will just be left out.

But reading null values is no problem.

If you want the library to explicitly write null values, I guess it would be possible to write a processor for that.

BestITUserEUW commented 4 months ago

@liuzicheng1987 Thanks for the fast answer. Is that something you could add to this library in the future ?

liuzicheng1987 commented 4 months ago

Yes, I think it's possible

liuzicheng1987 commented 4 months ago

@BestITUserEUW , by the way, if you want a quick fix to this problem, just add this to your code:


#include <rfl/json.hpp>

namespace rfl {
namespace parsing {

template <class ProcessorsType, class... FieldTypes>
requires AreReaderAndWriter<json::Reader,json::Writer,
                            NamedTuple<FieldTypes...>>
struct Parser<json::Reader, json::Writer, NamedTuple<FieldTypes...>,
              ProcessorsType>
    : public NamedTupleParser<json::Reader, json::Writer,
                              /*_ignore_empty_containers=*/false,
                              /*_all_required=*/true, ProcessorsType,
                              FieldTypes...> {
};

template <class ProcessorsType, class... Ts>
requires AreReaderAndWriter<json::Reader, json::Writer, std::tuple<Ts...>>
struct Parser<json::Reader, json::Writer, std::tuple<Ts...>,
              ProcessorsType>
    : public TupleParser<json::Reader, jso
::Writer,
                         /*_ignore_empty_containers=*/false,
                         /*_all_required=*/true, ProcessorsType, Ts...> {
};

}  // namespace parsing
}  // namespace rfl

It's not the most elegant solution, but it will get the job done while I think of something better.

liuzicheng1987 commented 4 months ago

@BestITUserEUW , I have created this feature branch:

https://github.com/getml/reflect-cpp/tree/f/json_null_values

It contains a preprocessor called rfl::NoOptionals. If you add that preprocessor to rfl::json::write, you will get the expected behaviour:

rfl::json::write<rfl::NoOptionals>(your_struct);

If you add it to read, it will also expect this when reading the JSON, making it stricter than the default:

rfl::json::read<YourStruct, rfl::NoOptionals>(json_string);

Here is a test that exemplifies the behaviour:

https://github.com/getml/reflect-cpp/blob/f/json_null_values/tests/json/test_no_optionals.cpp

Is this what you had in mind?

BestITUserEUW commented 4 months ago

@liuzicheng1987 Thank you for working on this i will have a look at it tomorrow.

BestITUserEUW commented 4 months ago

@liuzicheng1987 Thanks for adding this feature exactly what i needed. Just tested it out today.