Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default value returned on ValueType nlohmann::basic_json::value (const typename object_t::key_type& key, const ValueType& default_value) #1850

Closed
PixDay opened this issue Nov 22, 2019 · 3 comments
Labels
solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@PixDay
Copy link

PixDay commented Nov 22, 2019

nlohmann::json::value isn't returning the same value on an existing key :

#include "json.hpp"
#include <iostream>
#include <iomanip>

using json = nlohmann::json;

int main(void)
{
    char text[] = R"(
{
    "attributes" : {
        "aPosition" : "geometry[${geometryUuid}].position"
    },

    "techniques" : [{ "passes" : [{ "vertexShader" : "", "fragmentShader" : "" }] }]
}
)";
    
    json j = json::parse(text);
    json j2 = json::parse(text);
    
    json emptyarray = j.value("techniques", json::value_t::array);
    json techniques = j2.value("techniques", json::array());
    std::cout << "JSON CONTENT : " << std::setw(4) << j << std::endl;
    std::cout << "TECHNIQUES CONTENT : " + emptyarray.dump() << std::endl;
    std::cout << "TECHNIQUES CONTENT : " + techniques.dump() << std::endl;
    return 0;
}

output :

JSON CONTENT : {
    "attributes": {
        "aPosition": "geometry[${geometryUuid}].position"
    },
    "techniques": [
        {
            "passes": [
                {
                    "fragmentShader": "",
                    "vertexShader": ""
                }
            ]
        }
    ]
}
TECHNIQUES CONTENT : []
TECHNIQUES CONTENT : [{"passes":[{"fragmentShader":"","vertexShader":""}]}]
@nlohmann
Copy link
Owner

The code is correct:

json emptyarray = j.value("techniques", json::value_t::array);

calls function

template<class ValueType, typename std::enable_if<
             std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const

where ValueType deduced to const nlohmann::detail::value_t. The latter is an enum:

enum class value_t : std::uint8_t
{
    null,             ///< null value
    object,           ///< object (unordered set of name/value pairs)
    array,            ///< array (ordered collection of values)
    string,           ///< string value
    boolean,          ///< boolean value
    number_integer,   ///< number value (signed integer)
    number_unsigned,  ///< number value (unsigned integer)
    number_float,     ///< number value (floating-point)
    discarded         ///< discarded by the the parser callback function
};

Even if the value at key is found, the found value (a JSON array) will be converted to ValueType aka const nlohmann::detail::value_t. This is done via

constexpr operator value_t() const noexcept
{
    return m_type;
}

thus returning the type of the JSON value, which is json::value_t::array. Finally, this value is converted to nlohmann::json which results in an empty array.

In the end, json::value_t::array should not be used in client code other than to switch over a JSON value type like

switch (j.type())
{
	case(json::value_t::array):
	   ...
}

If you want to express "if key ' techniques' exists, use it or return an empty array otherwise", then

json techniques = j2.value("techniques", json::array());

is what you want.

@nlohmann nlohmann added solution: proposed fix a fix for the issue has been proposed and waits for confirmation and removed kind: bug labels Nov 22, 2019
@nlohmann
Copy link
Owner

Do you need further assistance with this issue?

@PixDay
Copy link
Author

PixDay commented Nov 27, 2019

Is it possible to express "if key 'techniques' exists, use it or return something that is not an array or an object"

@PixDay PixDay closed this as completed Nov 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

No branches or pull requests

2 participants