Skip to content

Commit 2fc0cb1

Browse files
committed
Improve invalid enum error message
1 parent 9b57d01 commit 2fc0cb1

2 files changed

Lines changed: 97 additions & 40 deletions

File tree

include/rfl/enums.hpp

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define RFL_ENUMS_HPP_
33

44
#include <string>
5+
#include <sstream>
56

67
#include "Result.hpp"
78
#include "internal/enums/get_enum_names.hpp"
@@ -11,6 +12,46 @@
1112

1213
namespace rfl {
1314

15+
// Returns a named tuple mapping names of enumerators of the given enum type to
16+
// their values.
17+
template <enchantum::Enum EnumType>
18+
auto get_enumerators() {
19+
return internal::enums::names_to_enumerator_named_tuple(
20+
internal::enums::get_enum_names<EnumType>());
21+
}
22+
23+
// Returns a named tuple mapping names of enumerators of the given enum type to
24+
// their underlying values.
25+
template <enchantum::Enum EnumType>
26+
auto get_underlying_enumerators() {
27+
return internal::enums::names_to_underlying_enumerator_named_tuple(
28+
internal::enums::get_enum_names<EnumType>());
29+
}
30+
31+
// Returns an std::array containing pairs of enumerator names (as
32+
// std::string_view) and values.
33+
template <enchantum::Enum EnumType>
34+
constexpr auto get_enumerator_array() {
35+
return internal::enums::names_to_enumerator_array(
36+
internal::enums::get_enum_names<EnumType>());
37+
}
38+
39+
// Returns an std::array containing pairs of enumerator names (as
40+
// std::string_view) and underlying values.
41+
template <enchantum::Enum EnumType>
42+
constexpr auto get_underlying_enumerator_array() {
43+
return internal::enums::names_to_underlying_enumerator_array(
44+
internal::enums::get_enum_names<EnumType>());
45+
}
46+
47+
// Returns the range of the given enum type as a pair of the minimum and maximum
48+
template <enchantum::Enum EnumType>
49+
constexpr auto get_enum_range() {
50+
return std::make_pair(enchantum::enum_traits<EnumType>::min,
51+
enchantum::enum_traits<EnumType>::max);
52+
}
53+
54+
// Converts an enum value to tis string representation.
1455
template <enchantum::Enum EnumType>
1556
std::string enum_to_string(const EnumType _enum) {
1657
const auto to_string_or_number = [](const EnumType e) {
@@ -52,7 +93,17 @@ Result<EnumType> string_to_enum(const std::string& _str) {
5293
try {
5394
return static_cast<EnumType>(std::stoi(name));
5495
} catch (std::exception& exp) {
55-
return error(exp.what());
96+
std::string msg = "Invalid enum value: '";
97+
msg += name;
98+
msg += "'. Must be one of [";
99+
const char* sep = "";
100+
for (const auto& p : get_enumerator_array<EnumType>()) {
101+
msg += sep;
102+
msg += p.first;
103+
sep = ", ";
104+
}
105+
msg += "].";
106+
return error(msg);
56107
}
57108
};
58109

@@ -74,45 +125,6 @@ Result<EnumType> string_to_enum(const std::string& _str) {
74125
}
75126
}
76127

77-
// Returns a named tuple mapping names of enumerators of the given enum type to
78-
// their values.
79-
template <enchantum::Enum EnumType>
80-
auto get_enumerators() {
81-
return internal::enums::names_to_enumerator_named_tuple(
82-
internal::enums::get_enum_names<EnumType>());
83-
}
84-
85-
// Returns a named tuple mapping names of enumerators of the given enum type to
86-
// their underlying values.
87-
template <enchantum::Enum EnumType>
88-
auto get_underlying_enumerators() {
89-
return internal::enums::names_to_underlying_enumerator_named_tuple(
90-
internal::enums::get_enum_names<EnumType>());
91-
}
92-
93-
// Returns an std::array containing pairs of enumerator names (as
94-
// std::string_view) and values.
95-
template <enchantum::Enum EnumType>
96-
constexpr auto get_enumerator_array() {
97-
return internal::enums::names_to_enumerator_array(
98-
internal::enums::get_enum_names<EnumType>());
99-
}
100-
101-
// Returns an std::array containing pairs of enumerator names (as
102-
// std::string_view) and underlying values.
103-
template <enchantum::Enum EnumType>
104-
constexpr auto get_underlying_enumerator_array() {
105-
return internal::enums::names_to_underlying_enumerator_array(
106-
internal::enums::get_enum_names<EnumType>());
107-
}
108-
109-
// Returns the range of the given enum type as a pair of the minimum and maximum
110-
template <enchantum::Enum EnumType>
111-
constexpr auto get_enum_range() {
112-
return std::make_pair(enchantum::enum_traits<EnumType>::min,
113-
enchantum::enum_traits<EnumType>::max);
114-
}
115-
116128
} // namespace rfl
117129

118130
#endif // RFL_ENUMS_HPP_
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <cassert>
2+
#include <rfl.hpp>
3+
#include <rfl/json.hpp>
4+
5+
#include <gtest/gtest.h>
6+
7+
namespace test_enum_error_messages {
8+
9+
enum class Color { red, green, blue, yellow };
10+
11+
TEST(json, test_enum_error_message_invalid_enum) {
12+
13+
const auto result = rfl::string_to_enum<Color>("bart");
14+
15+
const std::string expected = R"(Invalid enum value: 'bart'. Must be one of [red, green, blue, yellow].)";
16+
17+
EXPECT_TRUE(!result.has_value());
18+
19+
EXPECT_EQ(result.error().what(), expected);
20+
}
21+
22+
TEST(json, test_enum_error_message_empty_enum) {
23+
24+
const auto result = rfl::string_to_enum<Color>("");
25+
26+
const std::string expected = R"(Invalid enum value: ''. Must be one of [red, green, blue, yellow].)";
27+
28+
EXPECT_TRUE(!result.has_value());
29+
30+
EXPECT_EQ(result.error().what(), expected);
31+
}
32+
33+
TEST(json, test_enum_error_message_case_sensitive) {
34+
35+
const auto result = rfl::string_to_enum<Color>("RED");
36+
37+
const std::string expected = R"(Invalid enum value: 'RED'. Must be one of [red, green, blue, yellow].)";
38+
39+
EXPECT_TRUE(!result.has_value());
40+
41+
EXPECT_EQ(result.error().what(), expected);
42+
}
43+
44+
45+
} // namespace test_enum_error_messages

0 commit comments

Comments
 (0)