diff --git a/docs/index.rst b/docs/index.rst index 9d40731..a9b7ef0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,7 +12,7 @@ API Docs .. doxygenfunction:: errors::format -.. doxygenstruct:: errors::Error +.. doxygenclass:: errors::Error :members: License diff --git a/include/errors/error.hpp b/include/errors/error.hpp index cddeb39..26628b3 100644 --- a/include/errors/error.hpp +++ b/include/errors/error.hpp @@ -2,6 +2,7 @@ #include +#include #include #include #include @@ -11,8 +12,24 @@ namespace errors { /** * @brief Represents error information. */ -struct Error { - const std::string message; /**< The error message. */ +class Error { + private: + const std::shared_ptr message_ptr; + + public: + Error(const std::shared_ptr& message_ptr); + + /** + * @brief Returns the error message. + * + * @code{.cpp} + * const auto err = errors::make("unknown error"); + * + * // Print "unknown error" + * std::cout << err << std::endl; + * @endcode + */ + std::string message() const; /** * @brief Writes the string representation of an error object to the given diff --git a/src/error.cpp b/src/error.cpp index 30c2ef3..0e111fd 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -2,19 +2,28 @@ namespace errors { +Error::Error(const std::shared_ptr& message_ptr) : message_ptr(message_ptr) {} + +std::string Error::message() const { + if (!message_ptr) return "no error"; + return *message_ptr; +} + std::ostream& operator<<(std::ostream& os, const errors::Error& err) { - return os << "error: " << err.message; + return os << "error: " << err.message(); } bool operator==(const Error& lhs, const Error& rhs) { - return lhs.message == rhs.message; + return lhs.message() == rhs.message(); } bool operator!=(const Error& lhs, const Error& rhs) { - return lhs.message != rhs.message; + return lhs.message() != rhs.message(); } -Error make(const std::string& msg) { return Error{.message = msg}; } +Error make(const std::string& msg) { + return Error(std::make_shared(msg)); +} } // namespace error @@ -27,7 +36,7 @@ format_parse_context::iterator formatter::parse( format_context::iterator formatter::format( const errors::Error& err, format_context& ctx) const { - return format_to(ctx.out(), "error: {}", err.message); + return format_to(ctx.out(), "error: {}", err.message()); } } // namespace fmt diff --git a/test/error_test.cpp b/test/error_test.cpp index 28978ba..bc24dbd 100644 --- a/test/error_test.cpp +++ b/test/error_test.cpp @@ -7,12 +7,12 @@ TEST_CASE("Error Construction") { const errors::Error err = errors::make("unknown error"); - REQUIRE(err.message == "unknown error"); + REQUIRE(err.message() == "unknown error"); } TEST_CASE("Error Construction With Formatting") { const errors::Error err = errors::format("HTTP error {}", 404); - REQUIRE(err.message == "HTTP error 404"); + REQUIRE(err.message() == "HTTP error 404"); } TEST_CASE("Error Comparison") {