diff --git a/CMakeLists.txt b/CMakeLists.txt index 08d0ffbe..3267ff9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ cmake_policy(SET CMP0135 NEW) include("cmake/Hunter/init.cmake") -project(libp2p VERSION 0.0.1 LANGUAGES C CXX) +project(libp2p VERSION 0.1.14 LANGUAGES C CXX) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) diff --git a/cmake/Hunter/init.cmake b/cmake/Hunter/init.cmake index 882487c1..b205a37d 100644 --- a/cmake/Hunter/init.cmake +++ b/cmake/Hunter/init.cmake @@ -31,7 +31,7 @@ set( include(${CMAKE_CURRENT_LIST_DIR}/HunterGate.cmake) HunterGate( - URL "https://github.com/qdrvm/hunter/archive/refs/tags/v0.23.257-qdrvm1.zip" - SHA1 "e6aee2a8086d749d19d31d587f1f19c750a820ea" + URL https://github.com/qdrvm/hunter/archive/refs/tags/v0.23.257-qdrvm4.tar.gz + SHA1 da7f2ca25a1f79e809732175ab0b026f3ac89e39 LOCAL ) diff --git a/include/libp2p/log/sublogger.hpp b/include/libp2p/log/sublogger.hpp index 6a7fdeda..bf9f3f6a 100644 --- a/include/libp2p/log/sublogger.hpp +++ b/include/libp2p/log/sublogger.hpp @@ -12,6 +12,10 @@ namespace libp2p::log { + namespace fmt { + using namespace soralog::fmt; + } // namespace fmt + /// Local logger with common prefix used to distinguish message source /// instances class SubLogger { @@ -37,7 +41,7 @@ namespace libp2p::log { prefix_size_(prefix_.size()) {} template - void log(soralog::Level level, std::string_view fmt, const Args &... args) { + void log(soralog::Level level, std::string_view fmt, const Args &...args) { if (log_->level() >= level) { prefix_.append(fmt.data(), fmt.size()); log_->log(level, prefix_, args...); @@ -46,47 +50,47 @@ namespace libp2p::log { } template - void trace(std::string_view fmt, const Args &... args) { + void trace(std::string_view fmt, const Args &...args) { log(Level::TRACE, fmt, args...); } template - void debug(std::string_view fmt, const Args &... args) { + void debug(std::string_view fmt, const Args &...args) { log(Level::DEBUG, fmt, args...); } template - void verbose(std::string_view fmt, const Args &... args) { + void verbose(std::string_view fmt, const Args &...args) { log(Level::VERBOSE, fmt, args...); } template - void info(std::string_view fmt, const Args &... args) { + void info(std::string_view fmt, const Args &...args) { log(Level::INFO, fmt, args...); } template - void warn(std::string_view fmt, const Args &... args) { + void warn(std::string_view fmt, const Args &...args) { log(Level::WARN, fmt, args...); } template - void error(std::string_view fmt, const Args &... args) { + void error(std::string_view fmt, const Args &...args) { log(Level::ERROR, fmt, args...); } template - void critical(std::string_view fmt, const Args &... args) { + void critical(std::string_view fmt, const Args &...args) { log(Level::CRITICAL, fmt, args...); } private: template auto makePrefix(std::string_view prefix, T instance) { - if constexpr (std::is_pointer_v< - T> and not std::is_same_v) { - return fmt::format("{}({:x}): ", prefix, - reinterpret_cast(instance)); // NOLINT; + if constexpr (std::is_pointer_v + and not std::is_same_v) { + auto ptr_as_int = reinterpret_cast(instance); // NOLINT + return fmt::format("{}({:x}): ", prefix, ptr_as_int); } else if constexpr (std::is_integral_v and sizeof(T) > 1) { return fmt::format("{}#{}: ", prefix, instance); } else { diff --git a/include/libp2p/outcome/outcome.hpp b/include/libp2p/outcome/outcome.hpp index ee622f73..11a90155 100644 --- a/include/libp2p/outcome/outcome.hpp +++ b/include/libp2p/outcome/outcome.hpp @@ -10,6 +10,8 @@ #include #include +#include + // To define OUTCOME_TRY macro, we will need to create OUTCOME_TRY_1 and // OUTCOME_TRY_2 depending on number of arguments #define OUTCOME_TRY_1(...) BOOST_OUTCOME_TRY(__VA_ARGS__) @@ -43,4 +45,64 @@ namespace libp2p::outcome { // @see /docs/result.md +template <> +struct fmt::formatter { + // Parses format specifications. Must be empty + constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) { + // Parse the presentation format and store it in the formatter: + auto it = ctx.begin(), end = ctx.end(); + + // Check if reached the end of the range: + if (it != end && *it != '}') { + throw format_error("invalid format"); + } + + // Return an iterator past the end of the parsed range: + return it; + } + + // Formats the std::error_code + template + auto format(const std::error_code &ec, FormatContext &ctx) const + -> decltype(ctx.out()) { + // ctx.out() is an output iterator to write to. + + return soralog::fmt::format_to(ctx.out(), "{}", ec.message()); + } +}; + +template +struct fmt::formatter> { + // Parses format specifications. Must be empty + constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) { + // Parse the presentation format and store it in the formatter: + auto it = ctx.begin(), end = ctx.end(); + + // Check if reached the end of the range: + if (it != end && *it != '}') { + throw format_error("invalid format"); + } + + // Return an iterator past the end of the parsed range: + return it; + } + + // Formats the outcome result + template + auto format(const libp2p::outcome::result &res, + FormatContext &ctx) const -> decltype(ctx.out()) { + // ctx.out() is an output iterator to write to. + + if (res.has_value()) { + if constexpr (not std::is_void_v) { + return soralog::fmt::format_to(ctx.out(), "{}", res.value()); + } else { + return soralog::fmt::format_to(ctx.out(), ""); + } + } else { + return soralog::fmt::format_to(ctx.out(), "{}", res.error()); + } + } +}; + #endif // LIBP2P_OUTCOME_HPP diff --git a/test/libp2p/muxer/muxers_and_streams_test.cpp b/test/libp2p/muxer/muxers_and_streams_test.cpp index 00d1a54f..999ee150 100644 --- a/test/libp2p/muxer/muxers_and_streams_test.cpp +++ b/test/libp2p/muxer/muxers_and_streams_test.cpp @@ -60,7 +60,43 @@ namespace libp2p::regression { } return os; } +} // namespace libp2p::regression + +template <> +struct fmt::formatter { + // Parses format specifications. Must be empty + constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) { + // Parse the presentation format and store it in the formatter: + auto it = ctx.begin(), end = ctx.end(); + + // Check if reached the end of the range: + if (it != end && *it != '}') { + throw format_error("invalid format"); + } + + // Return an iterator past the end of the parsed range: + return it; + } + + // Formats the std::error_code + template + auto format(const libp2p::regression::Stats::Event &ev, + FormatContext &ctx) const -> decltype(ctx.out()) { + // ctx.out() is an output iterator to write to. + switch (ev) { +#define PRINT_EVENT(E) \ + case libp2p::regression::Stats::E: \ + return soralog::fmt::format_to(ctx.out(), #E); + EVENTS(PRINT_EVENT) +#undef PRINT_EVENT + default: + return soralog::fmt::format_to(ctx.out(), ""); + } + } +}; + +namespace libp2p::regression { class Node : public std::enable_shared_from_this { public: using Behavior = std::function; diff --git a/test/libp2p/protocol/gossip/CMakeLists.txt b/test/libp2p/protocol/gossip/CMakeLists.txt index bed9b82e..1b5a8747 100644 --- a/test/libp2p/protocol/gossip/CMakeLists.txt +++ b/test/libp2p/protocol/gossip/CMakeLists.txt @@ -7,6 +7,7 @@ addtest(gossip_structures_test target_link_libraries(gossip_structures_test p2p_gossip p2p_testutil_peer + p2p_basic_scheduler ) addtest(gossip_local_subs_test