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

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

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

No branches or pull requests

2 participants