83 lines
2.2 KiB
C++
83 lines
2.2 KiB
C++
#pragma once
|
|
|
|
#include "tl/detail/prologue.h"
|
|
#include "tl/detail/outcome.hpp"
|
|
#include "string.h"
|
|
#include "enum.h"
|
|
#include "format.h"
|
|
|
|
namespace tl
|
|
{
|
|
using namespace OUTCOME_V2_NAMESPACE;
|
|
|
|
template <typename CODE>
|
|
struct error
|
|
{
|
|
using code_t = CODE;
|
|
code_t code;
|
|
string what;
|
|
};
|
|
|
|
template <typename E, typename... Args>
|
|
E make_error(typename E::code_t code, std::format_string<Args...> format_str, Args&&... args) noexcept
|
|
{
|
|
return E{code, tl::format(format_str, std::forward<Args>(args)...)};
|
|
}
|
|
|
|
template <typename E>
|
|
E make_error(typename E::code_t code) noexcept
|
|
{
|
|
return E{code};
|
|
}
|
|
|
|
struct generic_error
|
|
{
|
|
string what;
|
|
};
|
|
|
|
template <typename... Args>
|
|
generic_error make_generic_error(std::format_string<Args...> format_str, Args&&... args) noexcept
|
|
{
|
|
return generic_error{tl::format(format_str, std::forward<Args>(args)...)};
|
|
}
|
|
|
|
template <typename R, typename E = generic_error>
|
|
using result = OUTCOME_V2_NAMESPACE::result<R, E, OUTCOME_V2_NAMESPACE::policy::terminate>;
|
|
|
|
template <class R, class S, class NoValuePolicy>
|
|
auto check(basic_result<R, S, NoValuePolicy>&& r) noexcept -> basic_result<R, S, NoValuePolicy>&&
|
|
{
|
|
TL_ASSERT(r.has_value(), "Result failed: {}", r.error());
|
|
return std::forward<basic_result<R, S, NoValuePolicy>>(r);
|
|
}
|
|
template <class R, class S, class NoValuePolicy>
|
|
auto ignore(basic_result<R, S, NoValuePolicy>&& r) noexcept -> basic_result<R, S, NoValuePolicy>&&
|
|
{
|
|
[[maybe_unused]] bool has = r.has_value();
|
|
return std::forward<basic_result<R, S, NoValuePolicy>>(r);
|
|
}
|
|
}
|
|
|
|
template <typename CODE>
|
|
struct std::formatter<tl::error<CODE>>
|
|
{
|
|
constexpr auto parse(format_parse_context& ctx) noexcept { return ctx.begin(); }
|
|
auto format(const tl::error<CODE>& e, std::format_context& ctx) const
|
|
{
|
|
if constexpr (std::is_enum_v<CODE>)
|
|
return format_to(ctx.out(), "code {}: {}", tl::enum_name(e.code), e.what);
|
|
else
|
|
return format_to(ctx.out(), "code {}: {}", e.code, e.what);
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct std::formatter<tl::generic_error>
|
|
{
|
|
constexpr auto parse(format_parse_context& ctx) noexcept { return ctx.begin(); }
|
|
auto format(const tl::generic_error& e, std::format_context& ctx) const
|
|
{
|
|
return format_to(ctx.out(), "{}", e.what);
|
|
}
|
|
};
|