Skip to content

Commit f6acdbe

Browse files
authored
Allow disabling default enum conversions (#3536)
1 parent e80945d commit f6acdbe

File tree

14 files changed

+172
-2
lines changed

14 files changed

+172
-2
lines changed

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ option(JSON_BuildTests "Build the unit tests when BUILD_TEST
4141
option(JSON_CI "Enable CI build targets." OFF)
4242
option(JSON_Diagnostics "Use extended diagnostic messages." OFF)
4343
option(JSON_ImplicitConversions "Enable implicit conversions." ON)
44+
option(JSON_DisableEnumSerialization "Disable default integer enum serialization." OFF)
4445
option(JSON_LegacyDiscardedValueComparison "Enable legacy discarded value comparison." OFF)
4546
option(JSON_Install "Install CMake targets during install step." ${MAIN_PROJECT})
4647
option(JSON_MultipleHeaders "Use non-amalgamated version of the library." ON)
@@ -78,6 +79,10 @@ if (NOT JSON_ImplicitConversions)
7879
message(STATUS "Implicit conversions are disabled")
7980
endif()
8081

82+
if (JSON_DisableEnumSerialization)
83+
message(STATUS "Enum integer serialization is disabled")
84+
endif()
85+
8186
if (JSON_LegacyDiscardedValueComparison)
8287
message(STATUS "Legacy discarded value comparison enabled")
8388
endif()
@@ -106,6 +111,7 @@ target_compile_definitions(
106111
${NLOHMANN_JSON_TARGET_NAME}
107112
INTERFACE
108113
$<$<NOT:$<BOOL:${JSON_ImplicitConversions}>>:JSON_USE_IMPLICIT_CONVERSIONS=0>
114+
$<$<BOOL:${JSON_DisableEnumSerialization}>:JSON_DISABLE_ENUM_SERIALIZATION=1>
109115
$<$<BOOL:${JSON_Diagnostics}>:JSON_DIAGNOSTICS=1>
110116
$<$<BOOL:${JSON_LegacyDiscardedValueComparison}>:JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1>
111117
)

cmake/ci.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -838,8 +838,8 @@ endfunction()
838838
ci_get_cmake(3.1.0 CMAKE_3_1_0_BINARY)
839839
ci_get_cmake(3.13.0 CMAKE_3_13_0_BINARY)
840840

841-
set(JSON_CMAKE_FLAGS_3_1_0 JSON_Diagnostics JSON_ImplicitConversions JSON_LegacyDiscardedValueComparison
842-
JSON_Install JSON_MultipleHeaders JSON_SystemInclude JSON_Valgrind)
841+
set(JSON_CMAKE_FLAGS_3_1_0 JSON_Diagnostics JSON_ImplicitConversions JSON_DisableEnumSerialization
842+
JSON_LegacyDiscardedValueComparison JSON_Install JSON_MultipleHeaders JSON_SystemInclude JSON_Valgrind)
843843
set(JSON_CMAKE_FLAGS_3_13_0 JSON_BuildTests)
844844

845845
function(ci_add_cmake_flags_targets flag min_version)

docs/docset/docSet.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ INSERT INTO searchIndex(name, type, path) VALUES ('SAX Interface', 'Guide', 'fea
140140
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_ASSERT', 'Macro', 'features/macros/index.html#json_assertx');
141141
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_CATCH_USER', 'Macro', 'features/macros/index.html#json_catch_userexception');
142142
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DIAGNOSTICS', 'Macro', 'features/macros/index.html#json_diagnostics');
143+
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_DISABLE_ENUM_SERIALIZATION', 'Macro', 'features/macros/index.html#json_disable_enum_serialization');
143144
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_11', 'Macro', 'features/macros/index.html#json_has_cpp_11-json_has_cpp_14-json_has_cpp_17-json_has_cpp_20');
144145
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_14', 'Macro', 'features/macros/index.html#json_has_cpp_11-json_has_cpp_14-json_has_cpp_17-json_has_cpp_20');
145146
INSERT INTO searchIndex(name, type, path) VALUES ('JSON_HAS_CPP_17', 'Macro', 'features/macros/index.html#json_has_cpp_11-json_has_cpp_14-json_has_cpp_17-json_has_cpp_20');

docs/mkdocs/docs/api/macros/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ header. See also the [macro overview page](../../features/macros.md).
2929

3030
## Type conversions
3131

32+
- [**JSON_DISABLE_ENUM_SERIALIZATION**](json_disable_enum_serialization.md) - switch off default serialization/deserialization functions for enums
3233
- [**JSON_USE_IMPLICIT_CONVERSIONS**](json_use_implicit_conversions.md) - control implicit conversions
3334

3435
<!-- comment-->
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# JSON_DISABLE_ENUM_SERIALIZATION
2+
3+
```cpp
4+
#define JSON_DISABLE_ENUM_SERIALIZATION
5+
```
6+
7+
When defined, default serialization and deserialization functions for enums are excluded and have to be provided by the user, for example, using [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md) (see [arbitrary type conversions](../../features/arbitrary_types.md) for more details).
8+
9+
Parsing or serializing an enum will result in a compiler error.
10+
11+
This works for both unscoped and scoped enums.
12+
13+
## Default definition
14+
15+
By default, `#!cpp JSON_DISABLE_ENUM_SERIALIZATION` is not defined.
16+
17+
```cpp
18+
#undef JSON_DISABLE_ENUM_SERIALIZATION
19+
```
20+
21+
## Examples
22+
23+
??? example "Example 1: Disabled behavior"
24+
25+
The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, meaning the code below **does not** compile.
26+
27+
```cpp
28+
#define JSON_DISABLE_ENUM_SERIALIZATION 1
29+
#include <nlohmann/json.hpp>
30+
31+
using json = nlohmann::json;
32+
33+
enum class Choice
34+
{
35+
first,
36+
second,
37+
};
38+
39+
int main()
40+
{
41+
// normally invokes to_json serialization function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not
42+
const json j = Choice::first;
43+
44+
// normally invokes from_json parse function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not
45+
Choice ch = j.get<Choice>();
46+
}
47+
```
48+
49+
??? example "Example 2: Serialize enum macro"
50+
51+
The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, but uses [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md) to parse and serialize the enum.
52+
53+
```cpp
54+
#define JSON_DISABLE_ENUM_SERIALIZATION 1
55+
#include <nlohmann/json.hpp>
56+
57+
using json = nlohmann::json;
58+
59+
enum class Choice
60+
{
61+
first,
62+
second,
63+
};
64+
65+
NLOHMANN_JSON_SERIALIZE_ENUM(Choice,
66+
{
67+
{ Choice::first, "first" },
68+
{ Choice::second, "second" },
69+
})
70+
71+
int main()
72+
{
73+
// uses user-defined to_json function defined by macro
74+
const json j = Choice::first;
75+
76+
// uses user-defined from_json function defined by macro
77+
Choice ch = j.get<Choice>();
78+
}
79+
```
80+
81+
??? example "Example 3: User-defined serialization/deserialization functions"
82+
83+
The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, but uses user-defined functions to parse and serialize the enum.
84+
85+
```cpp
86+
#define JSON_DISABLE_ENUM_SERIALIZATION 1
87+
#include <nlohmann/json.hpp>
88+
89+
using json = nlohmann::json;
90+
91+
enum class Choice
92+
{
93+
first,
94+
second,
95+
};
96+
97+
void from_json(const json& j, Choice& ch)
98+
{
99+
auto value = j.get<std::string>();
100+
if (value == "first")
101+
{
102+
ch = Choice::first;
103+
}
104+
else if (value == "second")
105+
{
106+
ch = Choice::second;
107+
}
108+
}
109+
110+
void to_json(json& j, const Choice& ch)
111+
{
112+
auto value = j.get<std::string>();
113+
if (value == "first")
114+
{
115+
ch = Choice::first;
116+
}
117+
else if (value == "second")
118+
{
119+
ch = Choice::second;
120+
}
121+
}
122+
123+
int main()
124+
{
125+
// uses user-defined to_json function
126+
const json j = Choice::first;
127+
128+
// uses user-defined from_json function
129+
Choice ch = j.get<Choice>();
130+
}
131+
```
132+
133+
## See also
134+
135+
- [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md)

docs/mkdocs/docs/api/macros/nlohmann_json_serialize_enum.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ inline void from_json(const BasicJsonType& j, type& e);
7878
## See also
7979
8080
- [Specializing enum conversion](../../features/enum_conversion.md)
81+
- [`JSON_DISABLE_ENUM_SERIALIZATION`](json_disable_enum_serialization.md)
8182
8283
## Version history
8384

docs/mkdocs/docs/features/enum_conversion.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,4 @@ Other Important points:
5858
default pair carefully.
5959
- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the
6060
map will be returned when converting to or from JSON.
61+
- To disable the default serialization of enumerators as integers and force a compiler error instead, see [`JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md).

docs/mkdocs/docs/features/macros.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ Exceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`.
5454

5555
See [full documentation of `JSON_NOEXCEPTION`](../api/macros/json_noexception.md).
5656

57+
## `JSON_DISABLE_ENUM_SERIALIZATION`
58+
59+
When defined, default parse and serialize functions for enums are excluded and have to be provided by the user, for example, using [`NLOHMANN_JSON_SERIALIZE_ENUM`](../api/macros/nlohmann_json_serialize_enum.md).
60+
61+
See [full documentation of `JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md).
62+
5763
## `JSON_NO_IO`
5864

5965
When defined, headers `<cstdio>`, `<ios>`, `<iosfwd>`, `<istream>`, and `<ostream>` are not included and parse functions

docs/mkdocs/mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ nav:
241241
- 'JSON_ASSERT': api/macros/json_assert.md
242242
- 'JSON_CATCH_USER': api/macros/json_throw_user.md
243243
- 'JSON_DIAGNOSTICS': api/macros/json_diagnostics.md
244+
- 'JSON_DISABLE_ENUM_SERIALIZATION': api/macros/json_disable_enum_serialization.md
244245
- 'JSON_HAS_CPP_11': api/macros/json_has_cpp_11.md
245246
- 'JSON_HAS_CPP_14': api/macros/json_has_cpp_11.md
246247
- 'JSON_HAS_CPP_17': api/macros/json_has_cpp_11.md

include/nlohmann/detail/conversions/from_json.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_int
139139
get_arithmetic_value(j, val);
140140
}
141141

142+
#if !JSON_DISABLE_ENUM_SERIALIZATION
142143
template<typename BasicJsonType, typename EnumType,
143144
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
144145
inline void from_json(const BasicJsonType& j, EnumType& e)
@@ -147,6 +148,7 @@ inline void from_json(const BasicJsonType& j, EnumType& e)
147148
get_arithmetic_value(j, val);
148149
e = static_cast<EnumType>(val);
149150
}
151+
#endif // JSON_DISABLE_ENUM_SERIALIZATION
150152

151153
// forward_list doesn't have an insert method
152154
template<typename BasicJsonType, typename T, typename Allocator,

0 commit comments

Comments
 (0)