LeviLamina
Loading...
Searching...
No Matches
Expected.h
1#pragma once
2
3#include <concepts>
4#include <memory>
5#include <string_view>
6
7#include "ll/api/base/Macro.h"
8#include "ll/api/io/LogLevel.h"
9
10#include "mc/server/commands/CommandOutputMessageType.h"
11
12class CommandOutput;
13
14namespace ll {
15class Error;
16
17template <class T = void>
18using Expected = ::nonstd::expected<T, ::ll::Error>;
19
20using Unexpected = ::nonstd::unexpected_type<::ll::Error>;
21
23 friend Error;
24 struct Impl;
25 std::unique_ptr<Impl> impl;
26
27public:
28 LLAPI ErrorInfoBase() noexcept;
29 LLAPI virtual ~ErrorInfoBase();
30
31 virtual std::string message() const noexcept = 0;
32};
33class Error {
34 mutable std::unique_ptr<ErrorInfoBase> mInfo;
35
36public:
37 Error& operator=(Error&&) noexcept = default;
38 Error& operator=(Error const&) noexcept = delete;
39 [[nodiscard]] Error(Error&&) noexcept = default;
40 [[nodiscard]] Error(Error const&) noexcept = delete;
41
42 LL_CONSTEXPR23 Error() noexcept = default;
43 LL_CONSTEXPR23 ~Error() noexcept = default;
44
45 LL_CONSTEXPR23 Error(std::unique_ptr<ErrorInfoBase> i) noexcept : mInfo(std::move(i)) {}
46
47 LL_CONSTEXPR23 Error(::nonstd::unexpected_type<::ll::Error> i) noexcept : Error(std::move(i.error())) {}
48
49 LL_CONSTEXPR23 operator bool() const noexcept { return mInfo != nullptr; }
50
51 LL_CONSTEXPR23 operator Unexpected() noexcept {
52 return ::nonstd::make_unexpected<Error>(std::in_place, std::move(mInfo));
53 }
54
55 LLNDAPI std::string message() const noexcept;
56
57 template <class T>
58 LL_CONSTEXPR23 bool isA() noexcept {
59 return mInfo ? typeid(T) == typeid(mInfo.get()) : false;
60 }
61 template <class T>
62 LL_CONSTEXPR23 T& as() noexcept {
63 return *static_cast<T*>(mInfo.get());
64 }
65 LLAPI Error& join(Error) noexcept;
66
67 LLAPI Error const& log(io::Logger&, io::LogLevel = io::LogLevel::Error) const noexcept;
68
69 LLAPI Error const& log(CommandOutput&, CommandOutputMessageType = CommandOutputMessageType::Error) const noexcept;
70};
71
73 std::string str;
74 StringError(std::string str) : str(std::move(str)) {}
75 std::string message() const noexcept override { return str; }
76};
78 std::error_code ec;
79 ErrorCodeError(std::error_code ec) : ec(ec) {}
80 std::string message() const noexcept override { return ec.message(); }
81};
82inline Unexpected forwardError(::ll::Error& err) noexcept { return ::nonstd::make_unexpected(std::move(err)); }
83
84inline Unexpected makeSuccessed() noexcept { return ::nonstd::make_unexpected(Error{}); }
85
86template <std::derived_from<::ll::ErrorInfoBase> T, class... Args>
87inline Unexpected makeError(Args&&... args) noexcept {
88 return ::nonstd::make_unexpected<Error>(std::in_place, std::make_unique<T>(std::forward<Args>(args)...));
89}
90inline Unexpected makeStringError(std::string str) noexcept { return makeError<StringError>(std::move(str)); }
91
92inline Unexpected makeErrorCodeError(std::error_code ec) noexcept { return makeError<ErrorCodeError>(ec); }
93
94inline Unexpected makeErrorCodeError(std::errc ec) noexcept { return makeError<ErrorCodeError>(make_error_code(ec)); }
95
96LLNDAPI Unexpected makeExceptionError(std::exception_ptr const& exc = std::current_exception()) noexcept;
97
98} // namespace ll
99
100namespace nonstd::expected_lite {
101template <>
102class bad_expected_access<::ll::Error> : public bad_expected_access<void> {
103 std::shared_ptr<::ll::Error> mError;
104 std::string mMessage;
105
106public:
107 explicit bad_expected_access(::ll::Error& e) noexcept
108 : mError(::std::make_shared<::ll::Error>(::std::move(e))),
109 mMessage(mError->message()) {}
110
111 char const* what() const noexcept override { return mMessage.c_str(); }
112
113 ::ll::Error& error() & { return *mError; }
114
115 ::ll::Error const& error() const& { return *mError; }
116
117 ::ll::Error&& error() && { return ::std::move(*mError); }
118
119 ::ll::Error const&& error() const&& { return ::std::move(*mError); }
120};
121template <>
122struct error_traits<::ll::Error> {
123 static void rethrow(::ll::Error const& e) { throw bad_expected_access<::ll::Error>{const_cast<::ll::Error&>(e)}; }
124};
125} // namespace nonstd::expected_lite
Definition CommandOutput.h:19
Definition Expected.h:22
Definition Expected.h:33
Definition Logger.h:25
Definition Expected.h:77
Definition Expected.h:72