diff --git a/include/colors.hpp b/include/colors.hpp index 8344de1..1d79596 100644 --- a/include/colors.hpp +++ b/include/colors.hpp @@ -3,52 +3,51 @@ #include "colors.hpp" #include +// #define GDPM_ENABLE_COLORS 1 #if GDPM_ENABLE_COLORS == 1 - #define GDPM_COLOR_BLACK "\033[0;30m" - #define GDPM_COLOR_BLUE "\033[0;34m" - #define GDPM_COLOR_GREEN "\033[0;32m" - #define GDPM_COLOR_CYAN "\033[0;36m" - #define GDPM_COLOR_RED "\033[0;31m" - #define GDPM_COLOR_PURPLE "\033[0;35m" - #define GDPM_COLOR_BROWN "\033[0;33m" - #define GDPM_COLOR_GRAY "\033[0;37m" - #define GDPM_COLOR_DARK_GRAY "\033[0;30m" - #define GDPM_COLOR_LIGHT_BLUE "\033[0;34m" - #define GDPM_COLOR_LIGHT_GREEN "\033[0;32m" - #define GDPM_COLOR_LIGHT_CYAN "\033[0;36m" - #define GDPM_COLOR_LIGHT_RED "\033[0;31m" - #define GDPM_COLOR_LIGHT_PURPLE "\033[0;35m" - #define GDPM_COLOR_YELLOW "\033[0;33m" - #define GDPM_COLOR_WHITE "\033[0;37m" - #define GDPM_COLOR_RESET GDPM_COLOR_WHITE + constexpr const char *GDPM_COLOR_BLACK = "\033[0;30m"; + constexpr const char *GDPM_COLOR_BLUE = "\033[0;34m"; + constexpr const char *GDPM_COLOR_GREEN = "\033[0;32m"; + constexpr const char *GDPM_COLOR_CYAN = "\033[0;36m"; + constexpr const char *GDPM_COLOR_RED = "\033[0;31m"; + constexpr const char *GDPM_COLOR_PURPLE = "\033[0;35m"; + constexpr const char *GDPM_COLOR_BROWN = "\033[0;33m"; + constexpr const char *GDPM_COLOR_GRAY = "\033[0;37m"; + constexpr const char *GDPM_COLOR_DARK_GRAY = "\033[0;30m"; + constexpr const char *GDPM_COLOR_LIGHT_BLUE = "\033[0;34m"; + constexpr const char *GDPM_COLOR_LIGHT_GREEN = "\033[0;32m"; + constexpr const char *GDPM_COLOR_LIGHT_CYAN = "\033[0;36m"; + constexpr const char *GDPM_COLOR_LIGHT_RED = "\033[0;31m"; + constexpr const char *GDPM_COLOR_LIGHT_PURPLE = "\033[0;35m"; + constexpr const char *GDPM_COLOR_YELLOW = "\033[0;33m"; + constexpr const char *GDPM_COLOR_WHITE = "\033[0;37m"; + constexpr const char *GDPM_COLOR_RESET = GDPM_COLOR_WHITE; #else - #define GDPM_COLOR_BLACK "" - #define GDPM_COLOR_BLUE "" - #define GDPM_COLOR_GREEN "" - #define GDPM_COLOR_CYAN "" - #define GDPM_COLOR_RED "" - #define GDPM_COLOR_PURPLE "" - #define GDPM_COLOR_BROWN "" - #define GDPM_COLOR_GRAY "" - #define GDPM_COLOR_DARK_GRAY "" - #define GDPM_COLOR_LIGHT_BLUE "" - #define GDPM_COLOR_LIGHT_GREEN "" - #define GDPM_COLOR_LIGHT_CYAN "" - #define GDPM_COLOR_LIGHT_RED "" - #define GDPM_COLOR_LIGHT_PURPLE "" - #define GDPM_COLOR_YELLOW "" - #define GDPM_COLOR_WHITE "" - #define GDPM_COLOR_RESET GDPM_COLOR_WHITE - - + constexpr const char *GDPM_COLOR_BLACK = ""; + constexpr const char *GDPM_COLOR_BLUE = ""; + constexpr const char *GDPM_COLOR_GREEN = ""; + constexpr const char *GDPM_COLOR_CYAN = ""; + constexpr const char *GDPM_COLOR_RED = ""; + constexpr const char *GDPM_COLOR_PURPLE = ""; + constexpr const char *GDPM_COLOR_BROWN = ""; + constexpr const char *GDPM_COLOR_GRAY = ""; + constexpr const char *GDPM_COLOR_DARK_GRAY = ""; + constexpr const char *GDPM_COLOR_LIGHT_BLUE = ""; + constexpr const char *GDPM_COLOR_LIGHT_GREEN = ""; + constexpr const char *GDPM_COLOR_LIGHT_CYAN = ""; + constexpr const char *GDPM_COLOR_LIGHT_RED = ""; + constexpr const char *GDPM_COLOR_LIGHT_PURPLE = ""; + constexpr const char *GDPM_COLOR_YELLOW = ""; + constexpr const char *GDPM_COLOR_WHITE = ""; + constexpr const char *GDPM_COLOR_RESET = GDPM_COLOR_WHITE; #endif -#define GDPM_COLOR_LOG_RESET GDPM_COLOR_WHITE -#define GDPM_COLOR_LOG_INFO GDPM_COLOR_LOG_RESET -#define GDPM_COLOR_LOG_ERROR GDPM_COLOR_RED -#define GDPM_COLOR_LOG_DEBUG GDPM_COLOR_YELLOW -#define GDPM_COLOR_LOG_WARNING GDPM_COLOR_YELLOW +constexpr const char *GDPM_COLOR_LOG_RESET = GDPM_COLOR_WHITE; +constexpr const char *GDPM_COLOR_LOG_INFO = GDPM_COLOR_LOG_RESET; +constexpr const char *GDPM_COLOR_LOG_ERROR = GDPM_COLOR_RED; +constexpr const char *GDPM_COLOR_LOG_DEBUG = GDPM_COLOR_YELLOW; +constexpr const char *GDPM_COLOR_LOG_WARNING = GDPM_COLOR_YELLOW; namespace gdpm::color{ inline std::string from_string(const std::string& color_name){ diff --git a/include/error.hpp b/include/error.hpp index ed75e56..07e9216 100644 --- a/include/error.hpp +++ b/include/error.hpp @@ -10,7 +10,7 @@ namespace gdpm::constants::error{ - enum { + enum class ec{ NONE = 0, UNKNOWN, UNKNOWN_COMMAND, @@ -75,36 +75,40 @@ namespace gdpm::constants::error{ }; - inline string get_message(int error_code) { + inline string get_message(ec error_code) { string message{}; - try{ message = messages[error_code]; } + try{ message = messages[(int)error_code]; } catch(const std::bad_alloc& e){ log::error("No default message for error code."); } return message; } + + template + inline T to(ec c){ return fmt::underlying_t(c); } }; namespace gdpm{ - namespace ec = constants::error; + using ec = constants::error::ec; + namespace ce = constants::error; class error { public: - constexpr explicit error(int code = 0, const string& message = "{default}"): + constexpr explicit error(ec code = ec::NONE, const string& message = "{default}"): m_code(code), - m_message(utils::replace_all(message, "{default}", ec::get_message(code))) + m_message(utils::replace_all(message, "{default}", ce::get_message(code))) {} - void set_code(int code) { m_code = code; } + void set_code(ec code) { m_code = code; } void set_message(const string& message) { m_message = message; } - int get_code() const { return m_code; } + ec get_code() const { return m_code; } string get_message() const { return m_message; } - bool has_occurred() const { return m_code != 0; } + bool has_occurred() const { return (int)m_code != 0; } bool operator()(){ return has_occurred(); } private: - int m_code; + ec m_code; string m_message; }; @@ -115,7 +119,7 @@ namespace gdpm{ set_prefix_if(std::format("[ERROR {}] ", utils::timestamp()), true); set_suffix_if("\n"); vlog( - fmt::format(GDPM_COLOR_LOG_ERROR "{}{}\n" GDPM_COLOR_LOG_RESET, prefix.contents, e.get_message()), + fmt::format("{}{}{}{}\n", GDPM_COLOR_LOG_ERROR, prefix.contents, e.get_message(), GDPM_COLOR_LOG_RESET), fmt::make_format_args(prefix.contents, e.get_message()) ); #endif @@ -130,7 +134,7 @@ namespace gdpm{ return e; } - static constexpr gdpm::error error_rc(int code, const string& message = "{default}"){ + static constexpr gdpm::error error_rc(ec code, const string& message = "{default}"){ return error_rc(gdpm::error(code, message)); } } diff --git a/include/log.hpp b/include/log.hpp index e0ede9c..3561af7 100644 --- a/include/log.hpp +++ b/include/log.hpp @@ -94,7 +94,7 @@ namespace gdpm::log set_prefix_if(fmt::format( get_info_prefix(), utils::timestamp()), true); set_suffix_if("\n"); vlog( - fmt::format(GDPM_COLOR_LOG_INFO "{}{}{}" GDPM_COLOR_LOG_RESET, prefix.contents, format, suffix), + fmt::format("{}{}{}{}{}", GDPM_COLOR_LOG_INFO, prefix.contents, format, suffix, GDPM_COLOR_LOG_RESET), fmt::make_format_args(args...) ); #endif @@ -108,7 +108,7 @@ namespace gdpm::log set_prefix_if(fmt::format(get_info_prefix(), utils::timestamp()), true); set_suffix_if("", true); vlog( - fmt::format(GDPM_COLOR_LOG_INFO "{}{}{}" GDPM_COLOR_LOG_RESET, prefix.contents, format, suffix), + fmt::format("{}{}{}{}{}", GDPM_COLOR_LOG_INFO, prefix.contents, format, suffix, GDPM_COLOR_LOG_RESET), fmt::make_format_args(args...) ); #endif @@ -122,7 +122,7 @@ namespace gdpm::log set_prefix_if(std::format(get_error_prefix(), utils::timestamp()), true); set_suffix_if("\n"); vlog( - fmt::format(GDPM_COLOR_LOG_ERROR "{}{}{}" GDPM_COLOR_LOG_RESET, prefix.contents, format, suffix), + std::format("{}{}{}{}{}", GDPM_COLOR_LOG_ERROR, prefix.contents, format, suffix, GDPM_COLOR_LOG_RESET), fmt::make_format_args(args...) ); #endif @@ -136,7 +136,7 @@ namespace gdpm::log set_prefix_if(std::format(get_debug_prefix(), utils::timestamp()), true); set_suffix_if("\n"); vlog( - fmt::format(GDPM_COLOR_LOG_DEBUG "{}{}{}" GDPM_COLOR_LOG_RESET, prefix.contents, format, suffix), + std::format("{}{}{}", GDPM_COLOR_LOG_DEBUG, prefix.contents, format, suffix, GDPM_COLOR_LOG_RESET), fmt::make_format_args(args...) ); #endif @@ -150,7 +150,7 @@ namespace gdpm::log set_prefix_if(std::format(get_warning_prefix(), utils::timestamp()), true); set_suffix_if("\n"); vlog( - fmt::format(GDPM_COLOR_LOG_WARNING "{}{}{}" GDPM_COLOR_LOG_RESET, prefix.contents, format, suffix), + std::format("{}{}{}", GDPM_COLOR_LOG_WARNING, prefix.contents, format, suffix, GDPM_COLOR_LOG_RESET), fmt::make_format_args(args...) ); #endif @@ -160,7 +160,7 @@ namespace gdpm::log template static constexpr void print(const S& format, Args&&...args){ vlog( - fmt::format("{}", format), + std::format("{}", format), fmt::make_format_args(args...) ); } @@ -168,7 +168,7 @@ namespace gdpm::log template static constexpr void println(const S& format, Args&&...args){ vlog( - fmt::format("{}\n", format), + std::format("{}\n", format), fmt::make_format_args(args...) ); } diff --git a/src/cache.cpp b/src/cache.cpp index aa8a593..09b62a2 100644 --- a/src/cache.cpp +++ b/src/cache.cpp @@ -173,7 +173,7 @@ namespace gdpm::cache{ sql += "COMMIT;\n"; rc = sqlite3_exec(db, sql.c_str(), callback, (void*)&p_vector, &errmsg); if(rc != SQLITE_OK){ - error error(constants::error::SQLITE_ERR, std::format( + error error(ec::SQLITE_ERR, std::format( "cache::get_package_info_by_id::sqlite3_exec(): {}", errmsg )); sqlite3_free(errmsg); diff --git a/src/config.cpp b/src/config.cpp index 9e5ddc8..c501b31 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -262,8 +262,7 @@ namespace gdpm::config{ else if(property == "verbosity") config.verbose = std::stoi(value); else if(property == "style") config.style = to_style(value); else{ - return log::error_rc(error( - constants::error::INVALID_CONFIG, + return log::error_rc(error(ec::INVALID_CONFIG, "Could not find property" )); } @@ -331,7 +330,7 @@ namespace gdpm::config{ error validate(const rapidjson::Document& doc){ - error error(constants::error::INVALID_CONFIG, ""); + error error(ec::INVALID_CONFIG, ""); if(!doc.IsObject()){ error.set_message("Document is not a JSON object."); return error; @@ -344,7 +343,7 @@ namespace gdpm::config{ error.set_message("Key `remote_sources` is not a JSON object."); return error; } - error.set_code(constants::error::NONE); + error.set_code(ec::NONE); return error; } diff --git a/src/http.cpp b/src/http.cpp index 468a73d..b5dfd36 100644 --- a/src/http.cpp +++ b/src/http.cpp @@ -4,6 +4,7 @@ #include "log.hpp" #include "error.hpp" #include +#include #include #include #include @@ -74,9 +75,7 @@ namespace gdpm::http{ curl_slist_free_all(list); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &r.code); if(res != CURLE_OK && params.verbose > 0) - log::error(ec::LIBCURL_ERR, - std::format("http::context::request::curl_easy_perform(): {}", curl_easy_strerror(res)) - ); + log::error("http::context::request::curl_easy_perform(): {}", (long)curl_easy_strerror(res)); curl_easy_cleanup(curl); } @@ -91,7 +90,7 @@ namespace gdpm::http{ const http::request& params ){ if(cm == nullptr){ - log::error(error(PRECONDITION_FAILED, + log::error(error(ec::PRECONDITION_FAILED, "http::multi::make_downloads(): multi client not initialized.") ); } @@ -173,7 +172,8 @@ namespace gdpm::http{ log::println("transfers left: {}", transfers_left); cres = curl_multi_remove_handle(cm, eh); if(cres != CURLM_OK){ - log::error("http::context::execute(): curl_multi_remove_handle() returned error {}", cres); + log::error(error(ec::LIBCURL_ERR, + std::format("http::context::execute(): curl_multi_remove_handle() returned error {}", (int)cres))); } curl_easy_cleanup(eh); transfers_left -= 1; @@ -190,13 +190,15 @@ namespace gdpm::http{ if(transfers_left){ cres = curl_multi_wait(cm, NULL, 0, params.timeout, NULL); if(cres != CURLM_OK){ - log::error("http::context::execute(): curl_multi_wait() returned an error {}", cres); + log::error(error(ec::LIBCURL_ERR, + std::format("http::context::execute(): curl_multi_wait() returned an error {}", (int)cres))); } } }while(transfers_left); cres = curl_multi_cleanup(cm); if(cres != CURLM_OK){ - log::error("http::context::execute(): curl_multi_cleanup() returned an error {}", cres); + log::error(error(ec::LIBCURL_ERR, + std::format("http::context::execute(): curl_multi_cleanup() returned an error {}", (int)cres))); } return responses(); } @@ -233,9 +235,7 @@ namespace gdpm::http{ /* Get response code, process error, save data, and close file. */ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &r.code); if(res != CURLE_OK && params.verbose > 0){ - log::error(ec::LIBCURL_ERR, - std::format("http::context::download_file::curl_easy_perform() failed: {}", curl_easy_strerror(res)) - ); + log::error("http::context::download_file::curl_easy_perform() failed: {}", curl_easy_strerror(res)); } fclose(fp); } @@ -285,9 +285,7 @@ namespace gdpm::http{ cres = curl_multi_add_handle(cm, curl); curl_slist_free_all(list); if(cres != CURLM_OK){ - log::error(ec::LIBCURL_ERR, - std::format("http::context::make_downloads(): {}", curl_multi_strerror(cres)) - ); + log::error("http::context::make_downstd::format(loads(): {}", curl_multi_strerror(cres)); } } transfers_index += 1; @@ -329,7 +327,7 @@ namespace gdpm::http{ } cres = curl_multi_remove_handle(cm, eh); if(cres != CURLM_OK){ - log::error("http::context::execute(): curl_multi_remove_handle() returned error {}", cres); + log::error("http::context::execute(): curl_multi_remove_handle() returned error {}", (int)cres); } transfers_left -= 1; curl_easy_cleanup(eh); @@ -348,13 +346,13 @@ namespace gdpm::http{ if(transfers_left){ cres = curl_multi_wait(cm, NULL, 0, params.timeout, NULL); if(cres != CURLM_OK){ - log::error("http::context::execute(): curl_multi_wait() returned an error {}", cres); + log::error("http::context::execute(): curl_multi_wait() returned an error {}", (int)cres); } } }while(transfers_left); cres = curl_multi_cleanup(cm); if(cres != CURLM_OK){ - log::error("http::context::execute(): curl_multi_cleanup() returned an error {}", cres); + log::error("http::context::execute(): curl_multi_cleanup() returned an error {}", (int)cres); } return responses(); } diff --git a/src/package.cpp b/src/package.cpp index 8fcb859..5fbd21a 100644 --- a/src/package.cpp +++ b/src/package.cpp @@ -219,7 +219,7 @@ namespace gdpm::package{ error error = cache::update_package_info(p_cache); if(error.has_occurred()){ string prefix = std::format(log::get_error_prefix(), utils::timestamp()); - log::println(GDPM_COLOR_LOG_ERROR"\n{}{}" GDPM_COLOR_RESET, prefix, error.get_message()); + log::println("\n{}{}{}{}", GDPM_COLOR_LOG_ERROR, prefix, error.get_message(), GDPM_COLOR_RESET); return error; } if(config.clean_temporary){ @@ -287,8 +287,7 @@ namespace gdpm::package{ if(is_missing_data){ doc = rest_api::get_asset(url, p.asset_id, rest_api_params); if(doc.HasParseError() || doc.IsNull()){ - return log::error_rc(error( - constants::error::JSON_ERR, + return log::error_rc(error(ec::JSON_ERR, std::format("Error parsing JSON: {}", GetParseError_En(doc.GetParseError())) )); } @@ -344,8 +343,7 @@ namespace gdpm::package{ if(response.code == http::OK){ log::println("Done."); }else{ - return log::error_rc(error( - constants::error::HTTP_RESPONSE_ERR, + return log::error_rc(error(ec::HTTP_RESPONSE_ERR, std::format("HTTP Error: {}", response.code) )); } @@ -710,8 +708,7 @@ namespace gdpm::package{ using namespace std::filesystem; if(params.paths.empty()){ - return log::error_rc(error( - constants::error::MALFORMED_PATH, + return log::error_rc(error(ec::MALFORMED_PATH, "Path is required" )); } @@ -721,8 +718,7 @@ namespace gdpm::package{ info_list p_found = {}; info_list p_cache = r_cache.unwrap_unsafe(); if(p_cache.empty()){ - return log::error_rc(error( - constants::error::NOT_FOUND, + return log::error_rc(error(ec::NOT_FOUND, "Could not find any packages to link in cache." )); } @@ -735,8 +731,7 @@ namespace gdpm::package{ } if(p_found.empty()){ - return log::error_rc(error( - constants::error::NO_PACKAGE_FOUND, + return log::error_rc(error(ec::NO_PACKAGE_FOUND, "No packages found to link." )); } @@ -755,7 +750,7 @@ namespace gdpm::package{ std::filesystem::create_directory_symlink(target, symlink_path, ec); if(ec){ log::error(error( - constants::error::STD_ERR, + ec::STD_ERR, std::format("Could not create symlink: {}", ec.message()) )); } @@ -774,8 +769,7 @@ namespace gdpm::package{ if(params.paths.empty()){ return log::error_rc(error( - constants::error::MALFORMED_PATH, - "Path is required" + ec::MALFORMED_PATH, "Path is required" )); } @@ -785,8 +779,7 @@ namespace gdpm::package{ /* Check for installed packages to clone */ if(p_cache.empty()){ - return log::error_rc(error( - constants::error::NO_PACKAGE_FOUND, + return log::error_rc(error(ec::NO_PACKAGE_FOUND, "Could not find any packages to clone in cache." )); } @@ -804,8 +797,7 @@ namespace gdpm::package{ } if(p_found.empty()){ - return log::error_rc(error( - constants::error::NO_PACKAGE_FOUND, + return log::error_rc(error(ec::NO_PACKAGE_FOUND, "No packages found to clone." )); } @@ -913,20 +905,18 @@ namespace gdpm::package{ void print_list(const info_list& packages){ for(const auto& p : packages){ log::println( - GDPM_COLOR_BLUE"{}/" - GDPM_COLOR_RESET "{}/{}/{} " - GDPM_COLOR_GREEN "v{} " - GDPM_COLOR_CYAN "{} " - GDPM_COLOR_RESET "Godot {}, {}", - p.support_level, - p.category, + "{}{}/{}/{}/{} {}\n\tv{} {} Godot {} {}{}", + GDPM_COLOR_GREEN, p.support_level, + p.category, p.author, p.title, + GDPM_COLOR_CYAN, p.version, p.modify_date, // p.asset_id, p.godot_version, - p.cost + p.cost, + GDPM_COLOR_RESET ); } } @@ -935,21 +925,18 @@ namespace gdpm::package{ void print_list(const rapidjson::Document& json){ for(const auto& o : json["result"].GetArray()){ log::println( - GDPM_COLOR_BLUE"{}/" - GDPM_COLOR_CYAN "{}/" - GDPM_COLOR_RESET "{}/{} " - GDPM_COLOR_GREEN "v{} " - GDPM_COLOR_CYAN "{} " - GDPM_COLOR_RESET "Godot {}, {}", - o["support_level"] .GetString(), + "{}{}/{}/{}/{} {}\n\tv{} {} Godot {} {}{}", + GDPM_COLOR_GREEN, o["support_level"].GetString(), utils::to_lower(o["category"].GetString()), - o["author"] .GetString(), - o["title"] .GetString(), - o["version_string"] .GetString(), - o["modify_date"] .GetString(), - // o["asset_id"] .GetString(), - o["godot_version"] .GetString(), - o["cost"] .GetString() + o["author"].GetString(), + o["title"].GetString(), + GDPM_COLOR_CYAN, + o["version_string"].GetString(), + o["modify_date"].GetString(), + // o["asset_id"].GetString(), + o["godot_version"].GetString(), + o["cost"].GetString(), + GDPM_COLOR_RESET ); } } diff --git a/src/remote.cpp b/src/remote.cpp index 62589ea..837ad2c 100644 --- a/src/remote.cpp +++ b/src/remote.cpp @@ -16,8 +16,7 @@ namespace gdpm::remote{ /* Check if enough args were provided. */ log::println("arg count: {}\nargs: {}", args.size(), utils::join(args)); if (args.size() < 2){ - return error( - constants::error::INVALID_ARG_COUNT, + return error(ec::INVALID_ARG_COUNT, "Requires a remote name and url argument" ); } @@ -35,8 +34,7 @@ namespace gdpm::remote{ ){ log::println("arg count: {}\nargs: {}", args.size(), utils::join(args)); if(args.size() < 1){ - return error( - constants::error::INVALID_ARG_COUNT, + return error(ec::INVALID_ARG_COUNT, "Requires at least one remote name argument" ); } diff --git a/src/rest_api.cpp b/src/rest_api.cpp index c273981..3fb3bca 100644 --- a/src/rest_api.cpp +++ b/src/rest_api.cpp @@ -242,9 +242,8 @@ namespace gdpm::rest_api{ const string_list& filters ){ if(urls.size() == asset_ids.size() && urls.size() == filters.size()){ - log::error(ec::ASSERTION_FAILED, - "multi::get_assets(): urls.size() != filters.size()" - ); + log::error(error(ec::ASSERTION_FAILED, + "multi::get_assets(): urls.size() != filters.size()")); } http::context http(4); http::request params; diff --git a/tests/basic.cpp b/tests/basic.cpp index ef071fc..dfcb7dd 100644 --- a/tests/basic.cpp +++ b/tests/basic.cpp @@ -80,8 +80,8 @@ TEST_CASE("Test configuration functions"){ std::string json = config::to_json(config); error error_save = config::save(config.path, config); - CHECK(error_save.get_code() == 0); + CHECK((int)error_save.get_code() == 0); error error_load = config::load(config.path, config); - CHECK(error_load.get_code() == 0); + CHECK((int)error_load.get_code() == 0); } \ No newline at end of file