summaryrefslogtreecommitdiff
path: root/src/core/error.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/error.cpp')
-rw-r--r--src/core/error.cpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/core/error.cpp b/src/core/error.cpp
new file mode 100644
index 0000000..727ca95
--- /dev/null
+++ b/src/core/error.cpp
@@ -0,0 +1,121 @@
+#include "error.h"
+
+namespace saw {
+error::error(error::code code_, bool is_critical__)
+ : error_code_{static_cast<error::code>(code_)}, is_critical_{is_critical__} {}
+
+error::error(error::code code_, bool is_critical__, const std::string_view &msg)
+ :
+ error_code_{static_cast<error::code>(code_)}
+ , is_critical_{is_critical__}, error_message_{msg}{}
+
+error::error(error &&error)
+ :
+ error_code_{std::move(error.error_code_)}
+ , is_critical_{std::move(error.is_critical_)}
+ , error_message_{std::move(error.error_message_)}{}
+
+const std::string_view error::message() const {
+
+ return std::visit(
+ [this](auto &&arg) -> const std::string_view {
+ using T = std::decay_t<decltype(arg)>;
+
+ if constexpr (std::is_same_v<T, std::string>) {
+ return std::string_view{arg};
+ } else if constexpr (std::is_same_v<T, std::string_view>) {
+ return arg;
+ } else {
+ return "Error in class Error. Good luck :)";
+ }
+ },
+ error_message_);
+}
+
+bool error::failed() const {
+ return this->is_error<err::no_error>();
+}
+
+bool error::is_critical() const {
+ return is_critical_;
+}
+
+bool error::is_recoverable() const {
+ return !is_critical_;
+}
+
+error error::copy_error() const {
+ auto copy_error_code = error_code_;
+ error error{copy_error_code, is_critical_};
+
+ try {
+ error.error_message_ = error_message_;
+ } catch (const std::bad_alloc &) {
+ error.error_message_ =
+ std::string_view{"Error while copying Error string. Out of memory"};
+ }
+
+ return error;
+}
+
+error::code error::get_id() const { return error_code_; }
+
+namespace impl {
+error_registry& get_error_registry() {
+ static own<error_registry> reg = nullptr;
+ if(!reg){
+ reg = heap<error_registry>();
+ }
+
+ assert(reg);
+ return *reg;
+}
+}
+
+error no_error(){
+ return make_error<err::no_error>();
+}
+
+namespace impl {
+error_or<error::code> error_registry::search_id(const std::string_view& desc)const{
+ /**
+ * Search the index in the vector
+ */
+ size_t i{};
+ size_t info_max_size = std::min<std::size_t>(infos.size(), std::numeric_limits<error::code>::max());
+ for(i = 0; i < info_max_size; ++i){
+ if(infos.at(i).description == desc){
+ break;
+ }
+ }
+
+ if(i == info_max_size){
+ return make_error<err::not_found>();
+ }
+
+ return static_cast<error::code>(i);
+}
+
+error_or<error::code> error_registry::search_or_register_id(const std::string_view& desc, bool is_critical){
+ auto err_or_id = search_id(desc);
+
+ if(err_or_id.is_value()){
+ return err_or_id.get_value();
+ }
+
+ auto& err = err_or_id.get_error();
+
+ if(err.is_error<err::not_found>()){
+ size_t new_index = infos.size();
+ if(new_index == std::numeric_limits<error::code>::max()){
+ return make_error<err::out_of_memory>("Error registry ids are exhausted");
+ }
+ infos.emplace_back(error_info{desc, is_critical});
+ return static_cast<error::code>(new_index);
+ }
+
+ return std::move(err);
+}
+}
+
+} // namespace saw