Skip to content

glz v4.4.2 force JSON input type to number via glz::meta #1641

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

Open
oftvk opened this issue Mar 7, 2025 · 0 comments
Open

glz v4.4.2 force JSON input type to number via glz::meta #1641

oftvk opened this issue Mar 7, 2025 · 0 comments

Comments

@oftvk
Copy link

oftvk commented Mar 7, 2025

For my use case I have to differentiate between different types of doubles (percentages vs amounts) which is done with strong typedefs as seen in the example struct. This works fine for structs containing the typedef but it doesn't work with variants.
It seems to violate the rule that no JSON type can occur twice in a variant as the schema states all types as JSON types as being possible (generated schema in 2nd example, parsing error in 3rd example).
Is it possible to only allow numbers as input to a custom read/write so I can use a variant like TestStruct below?

Struct

struct __declspec(empty_bases) StrongDouble  : type_safe::strong_typedef<StrongDouble, double>
{
    constexpr StrongDouble() : StrongDouble(0.0) {}

    explicit constexpr StrongDouble(double dVal) : strong_typedef(dVal) {}
};

struct TestStruct
{
    std::variant<std::string, StrongDouble> testing;
};

namespace glz
{
    template<>
    struct glz::meta<StrongDouble>
    {
        static constexpr auto read_strongDouble  = [](StrongDouble& strongDouble, const double& input) { 
            strongDouble = StrongDouble{ input }; 
        };
        static constexpr auto write_strongDouble = [](auto& strongDouble) -> auto& { return get(strongDouble); };
        static constexpr auto value              = glz::custom<read_strongDouble, write_strongDouble>;
    };
}

Schema

std::expected<std::string, glz::error_ctx> schema = glz::write_json_schema<TestStruct>();

results in:

{
    "type": [
        "object"
    ],
    "properties": {
        "testing": {
            "$ref": "#/$defs/std::variant<std::string,StrongDouble>"
        }
    },
    "additionalProperties": false,
    "$defs": {
        "std::variant<std::string,StrongDouble>": {
            "type": [
                "string"
            ],
            "oneOf": [
                {
                    "type": [
                        "string"
                    ],
                    "title": "std::string"
                },
                {
                    "type": [
                        "number",
                        "string",
                        "boolean",
                        "object",
                        "array",
                        "null"
                    ],
                    "title": "StrongDouble"
                }
            ]
        }
    }
}

Parsing

TestStruct inputStruct;
std::string inputString = "{ \"testing\": 1.1 }";
glz::error_ctx glazeError = glz::read_json<TestStruct, std::string&>(inputStruct, inputString);

results in:

2:11: no_matching_variant_type
       "input": {
             ^
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant