ReXGlue SDK
Loading...
Searching...
No Matches
result.h
Go to the documentation of this file.
1
10
11#pragma once
12
13#include <expected>
14#include <string>
15#include <utility>
16
17#include <rex/types.h>
18
19namespace rex {
20
24enum class ErrorCategory : u8 {
25 kNoError,
26 kIO,
27 kMemory,
30 kCompression,
31 kRuntime,
32 kPlatform,
33 kConfig,
35 kNotFound,
36 kNotImplemented,
37 kModule,
38};
39
43struct Error {
44 ErrorCategory category = ErrorCategory::kNoError;
45 std::string message;
46 int code = 0;
47
48 Error() = default;
49
55 Error(ErrorCategory cat, std::string msg, int err_code = 0)
56 : category(cat), message(std::move(msg)), code(err_code) {}
57
58 static Error FromErrno(ErrorCategory cat, std::string msg, int errno_value) {
59 return Error(cat, std::move(msg), errno_value);
60 }
61
67 [[nodiscard]] bool IsSuccess() const noexcept { return category == ErrorCategory::kNoError; }
68
73 [[nodiscard]] std::string GetDescription() const {
74 if (IsSuccess()) {
75 return "Success";
76 }
77 std::string result = message;
78 if (code != 0) {
79 result += " (code " + std::to_string(code) + ")";
80 }
81 return result;
82 }
83};
84
97template <typename T>
98using Result = std::expected<T, Error>;
99
105template <typename T>
106[[nodiscard]] inline Result<T> Ok(T&& value) {
107 return Result<T>(std::forward<T>(value));
108}
109
111[[nodiscard]] inline Result<void> Ok() {
112 return Result<void>();
113}
114
120template <typename T = void>
121inline auto Err(Error error) {
122 if constexpr (std::is_void_v<T>) {
123 return Result<void>(std::unexpected(std::move(error)));
124 } else {
125 return Result<T>(std::unexpected(std::move(error)));
126 }
127}
128
135template <typename T = void>
136inline auto Err(ErrorCategory category, std::string message, int code = 0) {
137 return Err<T>(Error(category, std::move(message), code));
138}
139
140} // namespace rex
141
151#define REX_TRY_PASTE(a, b) a##b
152
160#define REX_TRY_EXPAND_PASTE(a, b) REX_TRY_PASTE(a, b)
161
174// NOLINTBEGIN(bugprone-macro-parentheses): decl is a declaration
175#define REX_TRY(decl, expr) \
176 auto REX_TRY_EXPAND_PASTE(_rex_try_, __LINE__) = (expr); \
177 if (!REX_TRY_EXPAND_PASTE(_rex_try_, __LINE__)) { \
178 return std::unexpected(std::move(REX_TRY_EXPAND_PASTE(_rex_try_, __LINE__)).error()); \
179 } \
180 decl = *std::move(REX_TRY_EXPAND_PASTE(_rex_try_, __LINE__))
181// NOLINTEND(bugprone-macro-parentheses)
182
192#define REX_TRY_VOID(expr) \
193 do { \
194 auto&& _rex_try_status = (expr); \
195 if (!_rex_try_status) { \
196 return std::unexpected(std::move(_rex_try_status).error()); \
197 } \
198 } while (0)
199
209#define REX_ERROR_IF(cond, error) \
210 do { \
211 if (cond) { \
212 return std::unexpected(error); \
213 } \
214 } while (0)
Definition app.h:36
Result< T > Ok(T &&value)
Definition result.h:106
ErrorCategory
Definition result.h:24
@ kFormat
Definition result.h:28
@ kValidation
Definition result.h:34
@ kCrypto
Definition result.h:29
std::expected< T, Error > Result
Definition result.h:98
auto Err(Error error)
Definition result.h:121
Definition result.h:43
bool IsSuccess() const noexcept
Definition result.h:67
std::string GetDescription() const
Definition result.h:73
Error(ErrorCategory cat, std::string msg, int err_code=0)
Definition result.h:55
int code
Definition result.h:46
Integer types, byte order wrappers and size literals.