feat(error): basic error types

This commit is contained in:
maelstrom 2025-04-10 17:56:36 +02:00
parent 36397c1119
commit 595f3ebbe9
5 changed files with 113 additions and 0 deletions

17
core/src/error/error.cpp Normal file
View file

@ -0,0 +1,17 @@
#include "error.h"
#include "logger.h"
Error::Error(std::string message) : message(message) {
}
std::string Error::getMessage() {
return this->message;
}
void Error::logMessage(Logger::LogLevel logLevel) {
Logger::logf("%s", logLevel, this->message);
}
void Error::logMessageFatal() {
Logger::fatalErrorf("%s", this->message);
}

17
core/src/error/error.h Normal file
View file

@ -0,0 +1,17 @@
#pragma once
#include "logger.h"
#include <string>
// Base class for all errors
class Error {
std::string message;
protected:
Error(std::string message);
public:
std::string getMessage();
void logMessage(Logger::LogLevel logLevel = Logger::LogLevel::INFO);
void logMessageFatal();
};

View file

@ -0,0 +1,9 @@
#pragma once
#include "result.h"
struct DUMMY_VALUE;
template <typename ...E>
class fallible : public result<DUMMY_VALUE, E...> {
};

36
core/src/error/result.cpp Normal file
View file

@ -0,0 +1,36 @@
#include "result.h"
#include <optional>
#include <variant>
template <typename Result, typename ...E>
result<Result, E...>::result(Result value) : value(SuccessContainer { value }) {
}
template <typename Result, typename ...E>
result<Result, E...>::result(std::variant<E...> value) : value(ErrorContainer { value }) {
}
template <typename Result, typename ...E>
bool result<Result, E...>::is_success() {
return std::holds_alternative<SuccessContainer>(value);
}
template <typename Result, typename ...E>
bool result<Result, E...>::is_error() {
return std::holds_alternative<ErrorContainer>(value);
}
template <typename Result, typename ...E>
std::optional<Result> result<Result, E...>::success() {
return std::holds_alternative<SuccessContainer>(value) ? std::make_optional(std::get<SuccessContainer>(value).success) : std::nullopt;
}
template <typename Result, typename ...E>
std::optional<std::variant<E...>> result<Result, E...>::error() {
return std::holds_alternative<ErrorContainer>(value) ? std::make_optional(std::get<ErrorContainer>(value).error) : std::nullopt;
}
template <typename Result, typename ...E>
result<Result, E...>::operator std::optional<Result>() {
return this->success();
}

34
core/src/error/result.h Normal file
View file

@ -0,0 +1,34 @@
#pragma once
#include "error.h"
#include <optional>
#include <string>
#include <variant>
template <typename Result, typename ...E>
class [[nodiscard]] result {
struct ErrorContainer {
std::variant<E...> error;
};
struct SuccessContainer {
Result success;
};
std::variant<SuccessContainer, ErrorContainer> value;
public:
result(Result value);
result(std::variant<E...> value);
// Expects the result to be successful, otherwise panic with error message
Result expect(std::string errMsg = "Unwrapped a result with failure value");
bool is_success();
bool is_error();
std::optional<Result> success();
std::optional<std::variant<E...>> error();
// Equivalent to .success
operator std::optional<Result>();
};