Files
2026-11-03 15:22:24 -03:00

98 lines
2.7 KiB
C++

#pragma once
#include "hot_reload/Status.hpp"
#include <string>
#include <utility>
/**
* @file Result.hpp
* @brief hot_reload::Result -- what Context::load() and Context::reload() return.
*/
namespace hot_reload
{
/**
* @brief The outcome of one Context::load() or Context::reload() call: a Status, and the
* platform's own message when that status is a failure worth explaining.
*
* This replaces the C API's split between a returned `HotReloadStatus` and a separate,
* stateful `hot_reload_last_error()` call: every Result is self-contained, which is what
* makes it safe to use from multiple threads without the two ever referring to different
* calls -- see Context.hpp's own thread-safety note for why that split is not just a style
* preference here.
*
* @code
* hot_reload::Result result = ctx.load("plugin", "plugin.so");
* if (!result) // or !result.ok()
* {
* std::cerr << hot_reload::toString(result.status()) << ": " << result.message() << '\n';
* }
* @endcode
*/
class Result
{
public:
/**
* @brief Constructs a successful result.
* @return A Result whose status() is Status::Ok and whose message() is empty.
*/
[[nodiscard]] static Result success() noexcept;
/**
* @brief Constructs a failed result.
* @param status The failure's status; must not be Status::Ok (use ok() for that).
* @param message Why, in the platform's own words where there is one (see each
* Status enumerator's own doc comment for what it carries); may be empty for a
* failure that is fully explained by its status alone.
* @return A Result whose status() is @p status and whose message() is @p message.
*/
[[nodiscard]] static Result failure(Status status, std::string message = {}) noexcept;
/**
* @brief Whether this result represents success.
* @return True if status() is Status::Ok.
*/
[[nodiscard]] bool ok() const noexcept
{
return m_status == Status::Ok;
}
/// Equivalent to ok() -- lets a Result be used directly as `if (result)`.
[[nodiscard]] explicit operator bool() const noexcept
{
return ok();
}
/**
* @brief This result's status.
* @return The status passed to failure(), or Status::Ok for ok().
*/
[[nodiscard]] Status status() const noexcept
{
return m_status;
}
/**
* @brief This result's message.
* @return The message passed to failure(), or empty for ok() or a status that needed no
* further explanation.
*/
[[nodiscard]] const std::string& message() const noexcept
{
return m_message;
}
private:
Result(Status status, std::string message) noexcept
: m_status(status)
, m_message(std::move(message))
{
}
Status m_status;
std::string m_message;
};
}