174 lines
7.6 KiB
C++
174 lines
7.6 KiB
C++
#pragma once
|
|
|
|
#include <string_view>
|
|
#include <type_traits>
|
|
|
|
#include <ikarus/errors.h>
|
|
|
|
void safe_strcpy(
|
|
std::string_view const src,
|
|
char * dest,
|
|
size_t const dest_size
|
|
);
|
|
|
|
#define IKARUS_VOID_RETURN
|
|
|
|
#define IKARUS_SET_ERROR(msg, err_info) \
|
|
if (error_out != nullptr) { \
|
|
safe_strcpy( \
|
|
msg, \
|
|
static_cast<char *>(error_out->message), \
|
|
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_TRY_OR_FAIL_IMPL(var_name, msg, err_info, ...) \
|
|
auto var_name = __VA_ARGS__; \
|
|
if (var_name.is_error()) { \
|
|
IKARUS_SET_ERROR( \
|
|
fmt::format( \
|
|
fmt::runtime(msg), \
|
|
std::move(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( \
|
|
fmt::runtime(msg), \
|
|
std::move(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( \
|
|
fmt::runtime(msg), \
|
|
std::move(var_name).unwrap_error() \
|
|
), \
|
|
err_info \
|
|
); \
|
|
return var_name; \
|
|
} \
|
|
value = std::move(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(fmt::runtime(msg), var_name.unwrap_error()), \
|
|
err_info \
|
|
); \
|
|
return ret; \
|
|
} \
|
|
value = std::move(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_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_FAIL_IF_NAME_INVALID(name, ret) \
|
|
IKARUS_FAIL_IF_NULL(name, ret); \
|
|
IKARUS_FAIL_IF( \
|
|
cppbase::is_empty_or_blank(name), \
|
|
ret, \
|
|
#name " must not be empty", \
|
|
IkarusErrorInfo_Client_InvalidInput \
|
|
);
|
|
|
|
#define IKARUS_FAIL_IF_NOT_EXIST_IMPL(exists_name, object, ret) \
|
|
IKARUS_VTRYRV_OR_FAIL( \
|
|
auto exists_name, \
|
|
ret, \
|
|
fmt::format( \
|
|
"failed to check if {} exists", \
|
|
std::remove_cvref_t<decltype(*object)>::object_name \
|
|
), \
|
|
IkarusErrorInfo_Database_QueryFailed, \
|
|
object->project->db->query_one<bool>( \
|
|
fmt::format( \
|
|
"SELECT EXISTS(SELECT 1 FROM `{}` WHERE `id` = ?)", \
|
|
std::remove_cvref_t<decltype(*object)>::table_name \
|
|
), \
|
|
object->id \
|
|
) \
|
|
); \
|
|
\
|
|
IKARUS_FAIL_IF( \
|
|
!exists_name, \
|
|
ret, \
|
|
fmt::format( \
|
|
"{} doesn't exist", \
|
|
std::remove_cvref_t<decltype(*object)>::object_name \
|
|
), \
|
|
IkarusErrorInfo_Client_NonExistent \
|
|
)
|
|
|
|
#define IKARUS_FAIL_IF_NOT_EXIST(object, ret) \
|
|
IKARUS_FAIL_IF_NOT_EXIST_IMPL(CPPBASE_UNIQUE_NAME(exists), object, ret)
|