105 lines
3.8 KiB
C++
105 lines
3.8 KiB
C++
#pragma once
|
|
|
|
#include <boost/asio/awaitable.hpp>
|
|
#include <boost/system/errc.hpp>
|
|
#include <boost/system/error_code.hpp>
|
|
|
|
#include <expected>
|
|
|
|
namespace ranczo {
|
|
|
|
template < typename T >
|
|
using awaitable_expected = boost::asio::awaitable< std::expected< T, boost::system::error_code > >;
|
|
|
|
|
|
template < typename Tp, typename Er >
|
|
using expected = std::expected< Tp, Er >;
|
|
|
|
using _void = expected< void, boost::system::error_code >;
|
|
|
|
template < typename T >
|
|
using unexpected = std::unexpected< T >;
|
|
|
|
using ::boost::system::errc::make_error_code;
|
|
|
|
// // Try an awaitable that returns expected<T, E>, propagate error if present
|
|
// #define ASYNC_TRY(expr) \
|
|
// if(auto _res = co_await (expr); !_res) \
|
|
// co_return std::unexpected(_res.error())
|
|
|
|
#define SYNC_TRY(failable) \
|
|
({ \
|
|
auto _result = failable; \
|
|
if(!_result) \
|
|
return unexpected{_result.error()}; \
|
|
*_result; \
|
|
})
|
|
|
|
#define TRY(failable) \
|
|
({ \
|
|
auto _result = failable; \
|
|
if(!_result) \
|
|
co_return unexpected{_result.error()}; \
|
|
*_result; \
|
|
})
|
|
|
|
#define ASYNC_TRY(failable) \
|
|
({ \
|
|
auto _result = co_await (failable); \
|
|
if(!_result) \
|
|
co_return unexpected{_result.error()}; \
|
|
*_result; \
|
|
})
|
|
|
|
#define ASYNC_TRY_TRANSFORM_ERROR(failable, transform) \
|
|
({ \
|
|
auto _result = co_await (failable); \
|
|
if(!_result) \
|
|
co_return unexpected{transform(_result.error())}; \
|
|
*_result; \
|
|
})
|
|
|
|
#define ASYNC_TRY_MSG(failable, ...) \
|
|
({ \
|
|
auto _result = co_await (failable); \
|
|
if(!_result) { \
|
|
spdlog::error(__VA_ARGS__); \
|
|
co_return unexpected{_result.error()}; \
|
|
} \
|
|
*_result; \
|
|
})
|
|
|
|
// // Same as above, but log a custom message on error before propagating
|
|
// #define ASYNC_TRY_MSG(expr, ...) \
|
|
// if (auto _res = co_await (expr); !_res) { \
|
|
// spdlog::error(__VA_ARGS__); \
|
|
// co_return std::unexpected(_res.error()); \
|
|
// }
|
|
|
|
#define ASYNC_CHECK(failable) \
|
|
do { \
|
|
auto _result = co_await (failable); \
|
|
if(!_result) \
|
|
co_return std::unexpected(_result.error()); \
|
|
} while(0)
|
|
|
|
#define ASYNC_CHECK_MSG(failable, ...) \
|
|
do { \
|
|
auto _result = co_await (failable); \
|
|
if(!_result) { \
|
|
spdlog::error(__VA_ARGS__); \
|
|
co_return unexpected{_result.error()}; \
|
|
} \
|
|
} while(0)
|
|
|
|
// // Check an awaitable that returns expected<T, E>, but DO NOT propagate
|
|
// #define ASYNC_CHECK(expr) if(auto _res = co_await (expr); !_res)
|
|
|
|
// // Same as above, with custom log message
|
|
// #define ASYNC_CHECK_MSG(expr, msg) \
|
|
// if(auto _res = co_await (expr); !_res) { \
|
|
// spdlog::error("{}", msg); \
|
|
// }
|
|
|
|
} // namespace ranczo
|