diff --git a/nano/core_test/enums.cpp b/nano/core_test/enums.cpp index ae60532ed2..53b25a6d33 100644 --- a/nano/core_test/enums.cpp +++ b/nano/core_test/enums.cpp @@ -7,17 +7,59 @@ TEST (enums, stat_type) { ASSERT_FALSE (nano::to_string (static_cast (0)).empty ()); + ASSERT_NO_THROW (std::string{ nano::to_string (static_cast (0)) }); + ASSERT_FALSE (nano::to_string (nano::stat::type::_last).empty ()); + ASSERT_NO_THROW (std::string{ nano::to_string (nano::stat::type::_last) }); + ASSERT_EQ (nano::to_string (nano::stat::type::_last), "_last"); } TEST (enums, stat_detail) { ASSERT_FALSE (nano::to_string (static_cast (0)).empty ()); + ASSERT_NO_THROW (std::string{ nano::to_string (static_cast (0)) }); + ASSERT_FALSE (nano::to_string (nano::stat::detail::_last).empty ()); + ASSERT_NO_THROW (std::string{ nano::to_string (nano::stat::detail::_last) }); + ASSERT_EQ (nano::to_string (nano::stat::detail::_last), "_last"); } TEST (enums, stat_dir) { ASSERT_FALSE (nano::to_string (static_cast (0)).empty ()); + ASSERT_NO_THROW (std::string{ nano::to_string (static_cast (0)) }); + ASSERT_FALSE (nano::to_string (nano::stat::dir::_last).empty ()); + ASSERT_NO_THROW (std::string{ nano::to_string (nano::stat::dir::_last) }); + ASSERT_EQ (nano::to_string (nano::stat::dir::_last), "_last"); +} + +TEST (enums, log_type) +{ + ASSERT_FALSE (to_string (static_cast (0)).empty ()); + ASSERT_NO_THROW (std::string{ to_string (static_cast (0)) }); + + ASSERT_FALSE (to_string (nano::log::type::_last).empty ()); + ASSERT_NO_THROW (std::string{ to_string (nano::log::type::_last) }); + ASSERT_EQ (to_string (nano::log::type::_last), "_last"); +} + +TEST (enums, log_detail) +{ + ASSERT_FALSE (to_string (static_cast (0)).empty ()); + ASSERT_NO_THROW (std::string{ to_string (static_cast (0)) }); + + ASSERT_FALSE (to_string (nano::log::detail::_last).empty ()); + ASSERT_NO_THROW (std::string{ to_string (nano::log::detail::_last) }); + ASSERT_EQ (to_string (nano::log::detail::_last), "_last"); +} + +TEST (enums, log_category) +{ + ASSERT_FALSE (to_string (static_cast (0)).empty ()); + ASSERT_NO_THROW (std::string{ to_string (static_cast (0)) }); + + ASSERT_FALSE (to_string (nano::log::type::_last).empty ()); + ASSERT_NO_THROW (std::string{ to_string (nano::log::type::_last) }); + ASSERT_EQ (to_string (nano::log::type::_last), "_last"); } \ No newline at end of file diff --git a/nano/lib/logging_enums.cpp b/nano/lib/logging_enums.cpp index 3cc5163fc2..a7bbd1c7ba 100644 --- a/nano/lib/logging_enums.cpp +++ b/nano/lib/logging_enums.cpp @@ -21,12 +21,7 @@ std::string_view nano::log::to_string (nano::log::level level) const std::vector & nano::log::all_levels () { static std::vector all = [] () { - std::vector result; - for (auto const & lvl : magic_enum::enum_values ()) - { - result.push_back (lvl); - } - return result; + return nano::util::enum_values (); }(); return all; } @@ -34,19 +29,14 @@ const std::vector & nano::log::all_levels () const std::vector & nano::log::all_types () { static std::vector all = [] () { - std::vector result; - for (auto const & lvl : magic_enum::enum_values ()) - { - result.push_back (lvl); - } - return result; + return nano::util::enum_values (); }(); return all; } nano::log::level nano::log::parse_level (std::string_view name) { - auto value = magic_enum::enum_cast (name); + auto value = nano::util::parse_enum (name); if (value.has_value ()) { return value.value (); @@ -63,7 +53,7 @@ nano::log::level nano::log::parse_level (std::string_view name) nano::log::type nano::log::parse_type (std::string_view name) { - auto value = magic_enum::enum_cast (name); + auto value = nano::util::parse_enum (name); if (value.has_value ()) { return value.value (); @@ -76,7 +66,7 @@ nano::log::type nano::log::parse_type (std::string_view name) nano::log::detail nano::log::parse_detail (std::string_view name) { - auto value = magic_enum::enum_cast (name); + auto value = nano::util::parse_enum (name); if (value.has_value ()) { return value.value (); diff --git a/nano/lib/logging_enums.hpp b/nano/lib/logging_enums.hpp index 9effd61474..af2ebfda84 100644 --- a/nano/lib/logging_enums.hpp +++ b/nano/lib/logging_enums.hpp @@ -76,6 +76,8 @@ enum class type bootstrap, bootstrap_lazy, bootstrap_legacy, + + _last // Must be the last enum }; enum class detail @@ -112,6 +114,7 @@ enum class detail requesting_account_or_head, requesting_pending, + _last // Must be the last enum }; // TODO: Additionally categorize logs by categories which can be enabled/disabled independently @@ -121,6 +124,8 @@ enum class category work_generation, // ... + + _last // Must be the last enum }; } diff --git a/nano/lib/utility.hpp b/nano/lib/utility.hpp index 72ea310dae..61beefeeb4 100644 --- a/nano/lib/utility.hpp +++ b/nano/lib/utility.hpp @@ -14,6 +14,7 @@ #include #include +#include #include namespace boost @@ -262,4 +263,38 @@ std::string to_str (T const & val) { return boost::lexical_cast (val); } + +/** + * Same as `magic_enum::enum_values (...)` but ignores reserved values (starting with underscore) + */ +template +std::vector enum_values () +{ + std::vector result; + for (auto const & [val, name] : magic_enum::enum_entries ()) + { + if (!name.starts_with ('_')) + { + result.push_back (val); + } + } + return result; +} + +/** + * Same as `magic_enum::enum_cast (...)` but ignores reserved values (starting with underscore). + * Case insensitive. + */ +template +std::optional parse_enum (std::string_view name) +{ + if (name.starts_with ('_')) + { + return std::nullopt; + } + else + { + return magic_enum::enum_cast (name, magic_enum::case_insensitive); + } +} } \ No newline at end of file