Error converting to/from scoped enumerations
askr0x123456789 opened this issue · 3 comments
Description
nlohmann::json conversion from invalid json to scoped enumeration works without exceptions.
Reproduction steps
1- define a scoped enumeration
2- use NLOHMANN_JSON_SERIALIZE_ENUM
for convertion from string to the enum type
3- convert an invalid string to the enum type
Expected vs. actual results
Actual results:
color: "blue"
color (int): 0
color is red
color (int): 0
Minimal code example
enum class Color: int {
Red,
Green,
Blue
};
NLOHMANN_JSON_SERIALIZE_ENUM(Color, {
{Color::Red, "red"},
{Color::Green, "green"},
{Color::Blue, "blue"}
});
int main() {
auto blue = Color::Blue;
const nlohmann::json blueJson = blue;
fmt::println("color: {}", blueJson.dump()); // correct - works fine for valid enumerations
const nlohmann::json invalidColorJson = "yellow";
const Color invalidColor = invalidColorJson.get<Color>();
fmt::println("color (int): {}", static_cast<int>(invalidColor)); // output is 0 - which is wrong
if (invalidColor == Color::Red) { /// condition is true, which is wrong
fmt::println("color is red");
}
fmt::println("color (int): {}", static_cast<int>(Color::Red)); // output is 0 - correct
return EXIT_SUCCESS;
}
Error messages
No error message
Compiler and operating system
g++-14 on Kali Linux 2024.3
Library version
latest from develop branch
Validation
- The bug also occurs if the latest version from the
develop
branch is used. - I can successfully compile and run the unit tests.
You try to find an enum value for the string "yellow". The documentation states:
When using template get<ENUM_TYPE>(), undefined JSON values will default to the first specified conversion. Select this default pair carefully. See example 1 below.
Therefore, Color::Red
is returned.
Unless I misunderstood the issue, I would say that the library behaves as documented.
Shouldn't the correct behavior be throwing an exception?
I'm reading millions of records from a database and the available string value might be wrong.
If I'm not sure about the string values, converting a string to enum, is better be done by if statements.
I understand. The current macro behaves as documented, and changing it would break existing code. One possibility would be adding a throwing version of the macro.