Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 52 additions & 40 deletions include/rfl/enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define RFL_ENUMS_HPP_

#include <string>
#include <sstream>

#include "Result.hpp"
#include "internal/enums/get_enum_names.hpp"
Expand All @@ -11,6 +12,46 @@

namespace rfl {

// Returns a named tuple mapping names of enumerators of the given enum type to
// their values.
template <enchantum::Enum EnumType>
auto get_enumerators() {
return internal::enums::names_to_enumerator_named_tuple(
internal::enums::get_enum_names<EnumType>());
}

// Returns a named tuple mapping names of enumerators of the given enum type to
// their underlying values.
template <enchantum::Enum EnumType>
auto get_underlying_enumerators() {
return internal::enums::names_to_underlying_enumerator_named_tuple(
internal::enums::get_enum_names<EnumType>());
}

// Returns an std::array containing pairs of enumerator names (as
// std::string_view) and values.
template <enchantum::Enum EnumType>
constexpr auto get_enumerator_array() {
return internal::enums::names_to_enumerator_array(
internal::enums::get_enum_names<EnumType>());
}

// Returns an std::array containing pairs of enumerator names (as
// std::string_view) and underlying values.
template <enchantum::Enum EnumType>
constexpr auto get_underlying_enumerator_array() {
return internal::enums::names_to_underlying_enumerator_array(
internal::enums::get_enum_names<EnumType>());
}

// Returns the range of the given enum type as a pair of the minimum and maximum
template <enchantum::Enum EnumType>
constexpr auto get_enum_range() {
return std::make_pair(enchantum::enum_traits<EnumType>::min,
enchantum::enum_traits<EnumType>::max);
}

// Converts an enum value to tis string representation.
template <enchantum::Enum EnumType>
std::string enum_to_string(const EnumType _enum) {
const auto to_string_or_number = [](const EnumType e) {
Expand Down Expand Up @@ -52,7 +93,17 @@ Result<EnumType> string_to_enum(const std::string& _str) {
try {
return static_cast<EnumType>(std::stoi(name));
} catch (std::exception& exp) {
return error(exp.what());
std::string msg = "Invalid enum value: '";
msg += name;
msg += "'. Must be one of [";
const char* sep = "";
for (const auto& p : get_enumerator_array<EnumType>()) {
msg += sep;
msg += p.first;
sep = ", ";
}
msg += "].";
return error(msg);
}
};

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

// Returns a named tuple mapping names of enumerators of the given enum type to
// their values.
template <enchantum::Enum EnumType>
auto get_enumerators() {
return internal::enums::names_to_enumerator_named_tuple(
internal::enums::get_enum_names<EnumType>());
}

// Returns a named tuple mapping names of enumerators of the given enum type to
// their underlying values.
template <enchantum::Enum EnumType>
auto get_underlying_enumerators() {
return internal::enums::names_to_underlying_enumerator_named_tuple(
internal::enums::get_enum_names<EnumType>());
}

// Returns an std::array containing pairs of enumerator names (as
// std::string_view) and values.
template <enchantum::Enum EnumType>
constexpr auto get_enumerator_array() {
return internal::enums::names_to_enumerator_array(
internal::enums::get_enum_names<EnumType>());
}

// Returns an std::array containing pairs of enumerator names (as
// std::string_view) and underlying values.
template <enchantum::Enum EnumType>
constexpr auto get_underlying_enumerator_array() {
return internal::enums::names_to_underlying_enumerator_array(
internal::enums::get_enum_names<EnumType>());
}

// Returns the range of the given enum type as a pair of the minimum and maximum
template <enchantum::Enum EnumType>
constexpr auto get_enum_range() {
return std::make_pair(enchantum::enum_traits<EnumType>::min,
enchantum::enum_traits<EnumType>::max);
}

} // namespace rfl

#endif // RFL_ENUMS_HPP_
45 changes: 45 additions & 0 deletions tests/json/test_enum_error_messages.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <cassert>
#include <rfl.hpp>
#include <rfl/json.hpp>

#include <gtest/gtest.h>

namespace test_enum_error_messages {

enum class Color { red, green, blue, yellow };

TEST(json, test_enum_error_message_invalid_enum) {

const auto result = rfl::string_to_enum<Color>("bart");

const std::string expected = R"(Invalid enum value: 'bart'. Must be one of [red, green, blue, yellow].)";

EXPECT_TRUE(!result.has_value());

EXPECT_EQ(result.error().what(), expected);
}

TEST(json, test_enum_error_message_empty_enum) {

const auto result = rfl::string_to_enum<Color>("");

const std::string expected = R"(Invalid enum value: ''. Must be one of [red, green, blue, yellow].)";

EXPECT_TRUE(!result.has_value());

EXPECT_EQ(result.error().what(), expected);
}

TEST(json, test_enum_error_message_case_sensitive) {

const auto result = rfl::string_to_enum<Color>("RED");

const std::string expected = R"(Invalid enum value: 'RED'. Must be one of [red, green, blue, yellow].)";

EXPECT_TRUE(!result.has_value());

EXPECT_EQ(result.error().what(), expected);
}


} // namespace test_enum_error_messages
Loading