danielaparker / jsoncons

A C++, header-only library for constructing JSON and JSON-like data formats, with JSON Pointer, JSON Patch, JSON Schema, JSONPath, JMESPath, CSV, MessagePack, CBOR, BSON, UBJSON
https://danielaparker.github.io/jsoncons
Other
717 stars 163 forks source link

Added bool and null for as_double() #532

Closed MonkeybreadSoftware closed 2 months ago

MonkeybreadSoftware commented 3 months ago

The code doing JSON diffs can't compare as it would run the "not a double" exception, if one side has a number and other a null value. So we fix this by returning 0 here for double value.

danielaparker commented 2 months ago

The code doing JSON diffs can't compare as it would run the "not a double" exception, if one side has a number and other a null value. So we fix this by returning 0 here for double value.

Can you give an example of "The code doing JSON diffs" that fails? Thanks.

MonkeybreadSoftware commented 2 months ago

Here you go:

#include <jsoncons/json.hpp>
#include <jsoncons_ext/jmespath/jmespath.hpp>
#include <jsoncons_ext/jsonpatch/jsonpatch.hpp>
#include <jsoncons_ext/jsonpath/jsonpath.hpp>
#include <jsoncons_ext/mergepatch/mergepatch.hpp>

using namespace jsoncons;

json_options options;

int main(int argc, const char * argv[]) {
    // insert code here...
    options.lossless_number(true);
    options.bigint_format(bigint_chars_format::number);
    options.byte_string_format(byte_string_chars_format::base64);

    std::cout << "Hello, World!\n";

    const char* json1 = "{\"hello\":123.4, \"hello2\":null}";
    const char* json2 = "{\"hello\":null,  \"hello2\":123.4 }";

    ojson j1 = ojson::parse(json1, options);
    ojson j2 = ojson::parse(json2, options);

    std::string s1;
    std::string s2;
    std::string s3;
    j1.dump(s1);
    j2.dump(s2);

    std::cout << "s1: " << s1 << "\n";
    std::cout << "s2: " << s2 << "\n";

    ojson patch = jsonpatch::from_diff(j1, j2);
    patch.dump(s3);

    std::cout << "patch: " << s3 << "\n";

    return 0;
}

this would raise the exception for comparing double to null here.

danielaparker commented 2 months ago

The issue really is with the basic_json compare function, not as_double(). For lossless numbers, the compare function assumes that the other side of the compare supports as_double(), that may not be the case. In should handle other types in the same way that it does for numbers represented as int64_t, uint64_t and double. I've fixed that on master, and your example should now work.

MonkeybreadSoftware commented 2 months ago

Thank you.