Skip to content
New issue

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

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

Already on GitHub? # to your account

JSON as_or accessor #589

Open
supsm opened this issue Feb 3, 2025 · 3 comments
Open

JSON as_or accessor #589

supsm opened this issue Feb 3, 2025 · 3 comments

Comments

@supsm
Copy link

supsm commented Feb 3, 2025

Describe the proposed feature
It would be nice to have basic_json::as_or, which would be like get_value_or for as instead of at (i.e. converting the current basic_json value to the specified type if it matches, or some default value otherwise). This could be useful with at_or_null, which would allow the user to perform their own type checking and handling.

What other libraries (C++ or other) have this feature?
None that I'm aware of.

Include a code fragment with sample data that illustrates the use of this feature
Example 1:
The following code will not throw if the type is incorrect, which may be beneficial in some cases.
(note: this is modified from the example for get_value_or)
(also it seems like the example there is missing some usings :)

#include <jsoncons/json.hpp>

using jsoncons::json;
using jsoncons::json_object_arg;
using jsoncons::json_type;

int parse_category_string(std::string_view sv)
{
    return 0; // placeholder
}

int get_category_id(json j)
{
    json category = j.at_or_null("category");
    if (category.is_string())
    {
        return parse_category_string(category.as<std::string>());
    }
    return category.as_or<int>(100);
}

int main()
{
    json j1(json_object_arg, {{"author","Evelyn Waugh"},{"title","Sword of Honour"}});
    json j2(json_object_arg, {{"author", "J. R. R. Tolkien"}, {"title", "The Lord of the Rings"}, {"category", "fantasy"}});
    json j3(json_object_arg, {{"author", "Robert Louis Stevenson"}, {"title", "Strange Case of Dr Jekyll and Mr Hyde"}, {"category", 123}});

    std::cout << get_category_id(j1) << '\n';
    std::cout << get_category_id(j2) << '\n';
    std::cout << get_category_id(j3) << '\n';
}

Output:

100
0
123

Example 2:
This could also be used to massively simplify cases where invalid values are treated as a default value. In this example, if key is not found it will also use the default value (although this can be changed by using at instead of at_or_null). Provided j is a valid json object, this code will not throw.

json j = ...;
std::string str = j.at_or_null("key").as_or<std::string>("abcdef");
@danielaparker
Copy link
Owner

I agree. Would you care to submit a PR?

@supsm
Copy link
Author

supsm commented Feb 3, 2025

Sure, I will work on that. Are there any sort of guidelines for contributions (styling, etc)?

@danielaparker
Copy link
Owner

The function needs to be added to basic_json.hpp, just mimic the style of the related functions.

A catch TEST_CASE with one or more SECTION parts should be added to test/corelib/src/json_object_tests.cpp (compare with TEST_CASE("at_or_null test"))

A line of documentation should be added to doc/ref/corelib/basic_json.md, below at_or_null

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

2 participants