diff --git a/bin/examples/exception/main.cpp b/bin/examples/exception/main.cpp new file mode 100644 index 0000000..0d9863b --- /dev/null +++ b/bin/examples/exception/main.cpp @@ -0,0 +1,40 @@ +#include +#include "hack/exception/exception.hpp" +#include "hack/logger/logger.hpp" + +auto main(int argc, char *argv[]) -> int +{ + try + { + hack::exception e; + e.title("Test exception"); + e.description("Super description for test exception"); + e.service("example"); + std::vector vi = { 1, 2, 3 }; + e.set("vector int", vi); + e.set("int", 1); + e.set("float", 1.13f); + e.set("double", 1.23); + + // struct user_type + // { + // int i = 1; + // std::string str = "user type"; + // + // auto get_logger_data() + // { + // return std::make_tuple(i, str); + // } + // } ut; + // + // e.set("user type", ut); + throw e; + } + catch(hack::exception& e) + { + hack::log()(e); + } + + return 0; +} + diff --git a/bin/meson.build b/bin/meson.build index af450fc..86f0c2a 100755 --- a/bin/meson.build +++ b/bin/meson.build @@ -4,8 +4,9 @@ executable( # 'examples/concepts/main.cpp', # 'examples/math/main.cpp', # 'examples/range/main.cpp', - 'examples/patterns/main.cpp', + # 'examples/patterns/main.cpp', # 'examples/logger/main.cpp', + 'examples/exception/main.cpp', dependencies : deps, cpp_args: args, include_directories : inc diff --git a/src/hack/exception/exception.hpp b/src/hack/exception/exception.hpp index 6bcdc1e..aaf66cf 100644 --- a/src/hack/exception/exception.hpp +++ b/src/hack/exception/exception.hpp @@ -1,21 +1,18 @@ #pragma once -#include +#include #include - -#include "hack/utils/color.hpp" +#include #include "hack/exception/title.hpp" -// NOTE -// вмесо nlohman::json можно поробовать прикрутить https://jqlang.github.io/jq namespace hack { class exception { - using LOCATION = std::experimental::source_location; + using LOCATION = std::source_location; public: - exception(const std::experimental::source_location loc = LOCATION::current()) : m_location { loc } {} + exception(const LOCATION loc = LOCATION::current()) : m_location { loc } {} ~exception() = default; public: @@ -23,38 +20,18 @@ namespace hack void system_error(const std::exception& e) noexcept { m_system_error = e.what(); } void title(const std::string v) noexcept { m_title = v; } void description(const std::string v) noexcept { m_description = v; } - void set_data(std::any v) noexcept { m_data = v; } - std::any get_data() noexcept { return m_data; } + LOCATION get_location() const noexcept { return m_location; } - void log() - { - std::cout << utils::color::bold << utils::color::red <<"["+m_service+"] " << utils::color::reset - << m_location.file_name() << ":" - << utils::color::italic << utils::color::yellow << m_location.function_name() << "()" << utils::color::reset - << utils::color::bold << utils::color::blue << "[" << m_location.line() << "]" << utils::color::reset << ": " - << m_title << std::endl; - - if (!m_description.empty()) - std::cout << utils::color::bold << utils::color::red <<"["+m_service+"] " << utils::color::reset - << m_location.file_name() << ":" - << utils::color::italic << utils::color::yellow << m_location.function_name() << "()" << utils::color::reset - << utils::color::bold << utils::color::blue << "[" << m_location.line() << "]" << utils::color::reset << ": " - << m_description << std::endl; - - if (!m_system_error.empty()) - std::cout << utils::color::bold << utils::color::red <<"["+m_service+"] " << utils::color::reset - << m_location.file_name() << ":" - << utils::color::italic << utils::color::yellow << m_location.function_name() << "()" << utils::color::reset - << utils::color::bold << utils::color::blue << "[" << m_location.line() << "]" << utils::color::reset << ": " - << m_system_error << std::endl; - } + public: + void set(std::string key, std::any val) noexcept { m_data[key] = val; } + const std::unordered_map& get() const noexcept { return m_data; } private: - std::string m_service; - std::string m_system_error; - std::string m_title { exception_title::NO_VALID_DATA }; - std::string m_description; - std::experimental::source_location m_location; - std::any m_data; + std::string m_service; // имя сервиса где происходит исключение + std::string m_system_error; // системная ошибка + std::string m_title { exception_title::NO_VALID_DATA }; // название ошибки + std::string m_description; // описание этой ошибки + LOCATION m_location; // строка, где произошла ошибка + std::unordered_map m_data; // данные для логирования }; } diff --git a/src/hack/logger/logger.hpp b/src/hack/logger/logger.hpp index 918f2b2..7d782d1 100755 --- a/src/hack/logger/logger.hpp +++ b/src/hack/logger/logger.hpp @@ -8,6 +8,7 @@ #include "hack/concepts/concepts.hpp" #include "hack/iterators/sequence_ostream_iterator.hpp" #include "hack/iterators/associative_ostream_iterator.hpp" +#include "hack/exception/exception.hpp" // HERE // и нужно сделать реализацию где выводлится все в одной линии но при помощи цикла @@ -210,7 +211,7 @@ namespace hack } // для пользовательских типов - // у них должен быть отпределен метод get_data() + // у них должен быть отпределен метод get_logger_data() // возвращающий один из обработанных типов template void print_t(const T& rb) @@ -219,6 +220,71 @@ namespace hack print_t(rb.get_logger_data()); } + void print_t(const hack::exception& e) + { + auto loc = e.get_location(); + std::cout << utils::color::bold << utils::color::red; + std::cout << "exception: "; + std::cout << utils::color::reset; + std::cout << "{ "; + std::cout << "location: " << loc.file_name() << "[" << loc.line() << "]"; + std::cout << " }" << std::endl; + const auto& data = e.get(); + bool first = true; + for (const auto& [key, value] : data) + { + if (!first) std::cout << ", "; + + first = false; + std::cout << key << ": "; + + if (value.type() == typeid(std::string)) + { + // HERE + // хотельсь бы написать так: + // print_t(std::any_cast(value)); + // но по какой-то причине на эту запись ругается clangd + //  Client clangd quit with exit code 0 and signal 11. Check log for errors: /home/chatlanin/.local/state/nvim/lsp.log + // возможно это из-за концепта is_string + // по этому пише так: + print_t(std::any_cast(value).c_str()); + } + else if (value.type() == typeid(int)) + print_t(std::any_cast(value)); + else if (value.type() == typeid(double)) + print_t(std::any_cast(value)); + else if (value.type() == typeid(float)) + print_t(std::any_cast(value)); + else if (value.type() == typeid(bool)) + print_t(std::any_cast(value)); + // vector + else if (value.type() == typeid(std::vector)) + print_t(std::any_cast>(value)); + else if (value.type() == typeid(std::vector)) + print_t(std::any_cast>(value)); + else if (value.type() == typeid(std::vector)) + print_t(std::any_cast>(value)); + else if (value.type() == typeid(std::vector)) + print_t(std::any_cast>(value)); + // map + else if (value.type() == typeid(std::map)) + print_t(std::any_cast>(value)); + else if (value.type() == typeid(std::map)) + print_t(std::any_cast>(value)); + else if (value.type() == typeid(std::map)) + print_t(std::any_cast>(value)); + else if (value.type() == typeid(std::map)) + print_t(std::any_cast>(value)); + else + { + std::cout << utils::color::bold << utils::color::magenta; + print_t("[unsupported type]"); + std::cout << utils::color::reset; + } + } + std::cout << " }"; + } + private: std::source_location m_location; std::size_t m_count = 0; @@ -227,9 +293,6 @@ namespace hack bool m_no_file = m_base_config.m_no_file; bool m_no_row = m_base_config.m_no_row; bool m_bool_as_number = m_base_config.m_bool_as_number; - - friend class warn; - friend class error; }; // основная функция вызова логера