diff --git a/CMakeLists.txt b/CMakeLists.txt index 025203badf..f2e7a58f2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ option(DPP_INSTALL "Generate the install target" ON) option(DPP_BUILD_TEST "Build the test program" ON) option(DPP_NO_VCPKG "No VCPKG" OFF) option(DPP_CORO "Experimental support for C++20 coroutines" OFF) +option(DPP_FORMATTERS "Support for C++20 formatters" OFF) option(DPP_USE_EXTERNAL_JSON "Use an external installation of nlohmann::json" OFF) option(DPP_USE_PCH "Use precompiled headers to speed up compilation" OFF) option(AVX_TYPE "Force AVX type for speeding up audio mixing" OFF) diff --git a/include/dpp/snowflake.h b/include/dpp/snowflake.h index a2c5496625..109f16a53a 100644 --- a/include/dpp/snowflake.h +++ b/include/dpp/snowflake.h @@ -26,6 +26,10 @@ #include #include +#ifdef DPP_FORMATTERS +#include +#endif + /** * @brief The main namespace for D++ functions. classes and types */ @@ -281,3 +285,23 @@ struct std::hash return std::hash{}(s.value); } }; + +#ifdef DPP_FORMATTERS +/* + * @brief implementation of formater for dpp::snowflake for std::format support + * https://en.cppreference.com/w/cpp/utility/format/formatter + */ +template <> +struct std::formatter +{ + template + constexpr typename TP::iterator parse(TP& ctx) { + return ctx.begin(); + } + + template + typename TF::iterator format(const dpp::snowflake& snowflake, TF& ctx) const { + return std::format_to(ctx.out(), "{}", snowflake.str()); + } +}; +#endif //DPP_FORMATTERS diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index e0eac6632c..00b2a8b651 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -341,6 +341,10 @@ if(DPP_CORO) COMMAND php buildtools/make_struct.php "\\Dpp\\Generator\\CoroGenerator") endif() +if(DPP_FORMATTERS) + target_compile_definitions(dpp PUBLIC DPP_FORMATTERS) +endif() + if (DPP_BUILD_TEST) enable_testing(${CMAKE_CURRENT_SOURCE_DIR}/..) file(GLOB testnamelist "${CMAKE_CURRENT_SOURCE_DIR}/../src/*") @@ -351,7 +355,7 @@ if (DPP_BUILD_TEST) set (testsrc "") file(GLOB testsrc "${modules_dir}/${testname}/*.cpp") add_executable(${testname} ${testsrc}) - if (DPP_CORO) + if (DPP_CORO OR DPP_FORMATTERS) target_compile_features(${testname} PRIVATE cxx_std_20) else() target_compile_features(${testname} PRIVATE cxx_std_17) diff --git a/src/unittest/test.cpp b/src/unittest/test.cpp index 64440d4fcc..1af1301003 100644 --- a/src/unittest/test.cpp +++ b/src/unittest/test.cpp @@ -379,6 +379,19 @@ Markdown lol \\|\\|spoiler\\|\\| \\~\\~strikethrough\\~\\~ \\`small \\*code\\* b set_test(SNOWFLAKE, success); } + { // test snowflake: std::format support + + #ifdef DPP_FORMATTERS + set_test(SNOWFLAKE_STD_FORMAT, + std::format("{}",dpp::snowflake{}) == "0" && + std::format("{}",dpp::snowflake{12345}) == "12345" && + std::format("{} hello {}", dpp::snowflake{12345}, dpp::snowflake{54321}) == "12345 hello 54321" + ); + #else + set_status(SNOWFLAKE_STD_FORMAT,ts_skipped); + #endif // DPP_FORMATTERS + }; + { // test dpp::json_interface start_test(JSON_INTERFACE); struct fillable : dpp::json_interface { @@ -776,7 +789,7 @@ Markdown lol \\|\\|spoiler\\|\\| \\~\\~strikethrough\\~\\~ \\`small \\*code\\* b m5.get_url() == "" && m6.get_url() == "" && m7.get_url() == "" && - m8.get_url() == "" + m8.get_url() == "" ); } @@ -886,31 +899,31 @@ Markdown lol \\|\\|spoiler\\|\\| \\~\\~strikethrough\\~\\~ \\`small \\*code\\* b set_test(UTILITY_USER_URL, false); auto user_url = dpp::utility::user_url(123); - set_test(UTILITY_USER_URL, - user_url == dpp::utility::url_host + "/users/123" && + set_test(UTILITY_USER_URL, + user_url == dpp::utility::url_host + "/users/123" && dpp::utility::user_url(0) == "" ); set_test(UTILITY_MESSAGE_URL, false); auto message_url = dpp::utility::message_url(1,2,3); set_test(UTILITY_MESSAGE_URL, - message_url == dpp::utility::url_host+ "/channels/1/2/3" && + message_url == dpp::utility::url_host+ "/channels/1/2/3" && dpp::utility::message_url(0,2,3) == "" && - dpp::utility::message_url(1,0,3) == "" && + dpp::utility::message_url(1,0,3) == "" && dpp::utility::message_url(1,2,0) == "" && dpp::utility::message_url(0,0,3) == "" && dpp::utility::message_url(0,2,0) == "" && dpp::utility::message_url(1,0,0) == "" && - dpp::utility::message_url(0,0,0) == "" + dpp::utility::message_url(0,0,0) == "" ); set_test(UTILITY_CHANNEL_URL, false); auto channel_url = dpp::utility::channel_url(1,2); - set_test(UTILITY_CHANNEL_URL, + set_test(UTILITY_CHANNEL_URL, channel_url == dpp::utility::url_host+ "/channels/1/2" && dpp::utility::channel_url(0,2) == "" && dpp::utility::channel_url(1,0) == "" && - dpp::utility::channel_url(0,0) == "" + dpp::utility::channel_url(0,0) == "" ); set_test(UTILITY_THREAD_URL, false); @@ -919,7 +932,7 @@ Markdown lol \\|\\|spoiler\\|\\| \\~\\~strikethrough\\~\\~ \\`small \\*code\\* b thread_url == dpp::utility::url_host+ "/channels/1/2" && dpp::utility::thread_url(0,2) == "" && dpp::utility::thread_url(1,0) == "" && - dpp::utility::thread_url(0,0) == "" + dpp::utility::thread_url(0,0) == "" ); } @@ -1648,7 +1661,7 @@ Markdown lol \\|\\|spoiler\\|\\| \\~\\~strikethrough\\~\\~ \\`small \\*code\\* b set_test(TIMESTAMP, false); } } else { - set_test(MESSAGESGET, false); + set_test(MESSAGESGET, false); } } else { set_test(MESSAGESGET, false); diff --git a/src/unittest/test.h b/src/unittest/test.h index 9afd22879f..97637b7711 100644 --- a/src/unittest/test.h +++ b/src/unittest/test.h @@ -264,6 +264,8 @@ DPP_TEST(CORO_EVENT_HANDLER, "coro: online event handler", tf_online | tf_coro); DPP_TEST(CORO_API_CALLS, "coro: online api calls", tf_online | tf_coro); DPP_TEST(CORO_MUMBO_JUMBO, "coro: online mumbo jumbo in event handler", tf_online | tf_coro | tf_extended); +DPP_TEST(SNOWFLAKE_STD_FORMAT, "snowflake: std::format support", tf_offline); + void coro_offline_tests(); void coro_online_tests(dpp::cluster *bot);