93 lines
5 KiB
C++
93 lines
5 KiB
C++
#pragma once
|
|
|
|
#include <string_view>
|
|
|
|
#include <ikarus/errors.h>
|
|
|
|
inline void safe_strcpy(char * dest, std::string_view src, size_t dest_size) {
|
|
for (int i = 0; i < dest_size; ++i) {
|
|
if (src[i] == '\0') {
|
|
dest[i] = '\0';
|
|
return;
|
|
}
|
|
|
|
dest[i] = src[i];
|
|
}
|
|
}
|
|
|
|
#define IKARUS_SET_ERROR(msg, err_info) \
|
|
if (error_out != nullptr) { \
|
|
safe_strcpy(static_cast<char *>(error_out->message), msg, IKARUS_ERROR_DATA_MAX_MESSAGE_LIMIT); \
|
|
error_out->info = err_info; \
|
|
}
|
|
|
|
#define IKARUS_FAIL(ret, msg, err_info) \
|
|
IKARUS_SET_ERROR(msg, err_info); \
|
|
return ret
|
|
|
|
#define IKARUS_FAIL_IF(condition, ret, msg, err_info) \
|
|
if (condition) { \
|
|
IKARUS_SET_ERROR(msg, err_info) \
|
|
return ret; \
|
|
}
|
|
|
|
#define IKARUS_FAIL_IF_ERROR(ret) \
|
|
if (ikarus_error_data_is_error(error_out)) { \
|
|
return ret; \
|
|
}
|
|
|
|
#define IKARUS_FAIL_IF_NULL(ptr, ret) IKARUS_FAIL_IF(((ptr) == nullptr), ret, #ptr " must not be null", IkarusErrorInfo_Client_InvalidNull)
|
|
|
|
#define IKARUS_TRY_OR_FAIL_IMPL(var_name, msg, err_info, ...) \
|
|
auto var_name = __VA_ARGS__; \
|
|
if (var_name.is_error()) { \
|
|
IKARUS_SET_ERROR(fmt::format(msg, var_name.unwrap_error()), err_info); \
|
|
return var_name; \
|
|
}
|
|
|
|
#define IKARUS_TRY_OR_FAIL(msg, err_info, ...) IKARUS_TRY_OR_FAIL_IMPL(CPPBASE_UNIQUE_NAME(result), msg, err_info, __VA_ARGS__);
|
|
|
|
#define IKARUS_TRYRV_OR_FAIL_IMPL(var_name, ret, msg, err_info, ...) \
|
|
auto var_name = __VA_ARGS__; \
|
|
if (var_name.is_error()) { \
|
|
IKARUS_SET_ERROR(fmt::format(msg, var_name.unwrap_error()), err_info); \
|
|
return ret; \
|
|
}
|
|
|
|
#define IKARUS_TRYRV_OR_FAIL(ret, msg, err_info, ...) \
|
|
IKARUS_TRYRV_OR_FAIL_IMPL(CPPBASE_UNIQUE_NAME(result), ret, msg, err_info, __VA_ARGS__);
|
|
|
|
#define IKARUS_VTRY_OR_FAIL_IMPL(var_name, value, msg, err_info, ...) \
|
|
auto var_name = __VA_ARGS__; \
|
|
if (var_name.is_error()) { \
|
|
IKARUS_SET_ERROR(fmt::format(msg, var_name.unwrap_error()), err_info); \
|
|
return var_name; \
|
|
} \
|
|
value = var_name.unwrap_value()
|
|
|
|
#define IKARUS_VTRY_OR_FAIL(value, msg, err_info, ...) \
|
|
IKARUS_VTRY_OR_FAIL_IMPL(CPPBASE_UNIQUE_NAME(result), value, msg, err_info, __VA_ARGS__);
|
|
|
|
#define IKARUS_VTRYRV_OR_FAIL_IMPL(var_name, value, ret, msg, err_info, ...) \
|
|
auto var_name = __VA_ARGS__; \
|
|
if (var_name.is_error()) { \
|
|
IKARUS_SET_ERROR(fmt::format(msg, var_name.unwrap_error()), err_info); \
|
|
return ret; \
|
|
} \
|
|
value = var_name.unwrap_value()
|
|
|
|
#define IKARUS_VTRYRV_OR_FAIL(value, ret, msg, err_info, ...) \
|
|
IKARUS_VTRYRV_OR_FAIL_IMPL(CPPBASE_UNIQUE_NAME(result), value, ret, msg, err_info, __VA_ARGS__);
|
|
|
|
#define IKARUS_FAIL_IF_OBJECT_MISSING_IMPL(var_name, obj, ret) \
|
|
IKARUS_VTRYRV_OR_FAIL( \
|
|
bool const var_name, \
|
|
ret, \
|
|
"unable to check whether object exists: {}", \
|
|
IkarusErrorInfo_Database_QueryFailed, \
|
|
(obj)->project->db->template query_one<bool>("SELECT EXISTS(SELECT 1 FROM `objects` WHERE `id` = ?)", (obj)->id) \
|
|
) \
|
|
\
|
|
IKARUS_FAIL_IF(!(var_name), ret, "object does not exist", IkarusErrorInfo_Client_Misuse);
|
|
|
|
#define IKARUS_FAIL_IF_OBJECT_MISSING(obj, ret) IKARUS_FAIL_IF_OBJECT_MISSING_IMPL(CPPBASE_UNIQUE_NAME(exists), obj, ret);
|