2022-12-13 10:39:57 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <BAN/Formatter.h>
|
2023-05-22 19:54:59 +03:00
|
|
|
#include <BAN/StringView.h>
|
2023-02-22 01:23:11 +02:00
|
|
|
#include <BAN/Variant.h>
|
2022-12-13 10:39:57 +02:00
|
|
|
|
2023-03-02 21:10:44 +02:00
|
|
|
#include <errno.h>
|
2022-12-13 12:10:50 +02:00
|
|
|
#include <string.h>
|
|
|
|
|
2023-05-22 19:54:59 +03:00
|
|
|
#ifdef __is_kernel
|
2023-01-09 14:56:20 +02:00
|
|
|
#include <kernel/Panic.h>
|
2023-04-11 23:25:21 +03:00
|
|
|
#include <kernel/Errors.h>
|
2023-04-19 00:29:16 +03:00
|
|
|
#define MUST(expr) ({ auto&& e = expr; if (e.is_error()) Kernel::panic("{}", e.error()); e.release_value(); })
|
|
|
|
#define MUST_REF(expr) *({ auto&& e = expr; if (e.is_error()) Kernel::panic("{}", e.error()); &e.release_value(); })
|
2022-12-13 10:39:57 +02:00
|
|
|
#else
|
2023-06-03 18:53:05 +03:00
|
|
|
#include <assert.h>
|
2023-04-19 00:29:16 +03:00
|
|
|
#define MUST(expr) ({ auto&& e = expr; assert(!e.is_error()); e.release_value(); })
|
|
|
|
#define MUST_REF(expr) *({ auto&& e = expr; assert(!e.is_error()); &e.release_value(); })
|
2022-12-13 10:39:57 +02:00
|
|
|
#endif
|
|
|
|
|
2023-04-19 00:29:16 +03:00
|
|
|
#define TRY(expr) ({ auto&& e = expr; if (e.is_error()) return e.release_error(); e.release_value(); })
|
|
|
|
#define TRY_REF(expr) *({ auto&& e = expr; if (e.is_error()) return e.release_error(); &e.release_value(); })
|
2022-12-13 10:39:57 +02:00
|
|
|
|
2023-01-17 11:38:16 +02:00
|
|
|
namespace BAN
|
2022-12-13 10:39:57 +02:00
|
|
|
{
|
|
|
|
|
2023-01-17 11:38:16 +02:00
|
|
|
class Error
|
|
|
|
{
|
2023-05-22 19:54:59 +03:00
|
|
|
#ifdef __is_kernel
|
2023-04-11 23:25:21 +03:00
|
|
|
private:
|
2023-05-07 02:09:52 +03:00
|
|
|
static constexpr uint64_t kernel_error_mask = uint64_t(1) << 63;
|
2023-05-22 19:54:59 +03:00
|
|
|
#endif
|
2023-04-11 23:25:21 +03:00
|
|
|
|
2023-01-17 11:38:16 +02:00
|
|
|
public:
|
2023-05-22 19:54:59 +03:00
|
|
|
#ifdef __is_kernel
|
2023-04-11 23:25:21 +03:00
|
|
|
static Error from_error_code(Kernel::ErrorCode error)
|
2023-01-17 11:38:16 +02:00
|
|
|
{
|
2023-05-07 02:09:52 +03:00
|
|
|
return Error((uint64_t)error | kernel_error_mask);
|
2023-01-17 11:38:16 +02:00
|
|
|
}
|
2023-05-22 19:54:59 +03:00
|
|
|
#endif
|
2023-04-11 23:25:21 +03:00
|
|
|
static Error from_errno(int error)
|
2023-03-08 17:05:37 +02:00
|
|
|
{
|
2023-04-11 23:25:21 +03:00
|
|
|
return Error(error);
|
2023-03-08 17:05:37 +02:00
|
|
|
}
|
2023-04-11 23:25:21 +03:00
|
|
|
|
2023-05-22 19:54:59 +03:00
|
|
|
#ifdef __is_kernel
|
2023-04-11 23:25:21 +03:00
|
|
|
Kernel::ErrorCode kernel_error() const
|
2023-03-02 21:10:44 +02:00
|
|
|
{
|
2023-04-11 23:25:21 +03:00
|
|
|
return (Kernel::ErrorCode)(m_error_code & ~kernel_error_mask);
|
2023-03-02 21:10:44 +02:00
|
|
|
}
|
2023-08-29 00:13:21 +03:00
|
|
|
|
|
|
|
bool is_kernel_error() const
|
|
|
|
{
|
|
|
|
return m_error_code & kernel_error_mask;
|
|
|
|
}
|
2023-05-22 19:54:59 +03:00
|
|
|
#endif
|
2023-01-17 11:38:16 +02:00
|
|
|
|
2023-05-07 02:09:52 +03:00
|
|
|
uint64_t get_error_code() const { return m_error_code; }
|
2023-04-11 23:25:21 +03:00
|
|
|
BAN::StringView get_message() const
|
|
|
|
{
|
2023-05-22 19:54:59 +03:00
|
|
|
#ifdef __is_kernel
|
2023-04-11 23:25:21 +03:00
|
|
|
if (m_error_code & kernel_error_mask)
|
|
|
|
return Kernel::error_string(kernel_error());
|
2023-05-22 19:54:59 +03:00
|
|
|
#endif
|
2023-04-11 23:25:21 +03:00
|
|
|
return strerror(m_error_code);
|
|
|
|
}
|
2023-01-17 11:38:16 +02:00
|
|
|
|
|
|
|
private:
|
2023-05-07 02:09:52 +03:00
|
|
|
Error(uint64_t error)
|
2023-04-11 23:25:21 +03:00
|
|
|
: m_error_code(error)
|
|
|
|
{}
|
|
|
|
|
2023-05-07 02:09:52 +03:00
|
|
|
uint64_t m_error_code;
|
2023-01-17 11:38:16 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
template<typename T>
|
2023-02-19 20:10:30 +02:00
|
|
|
class [[nodiscard]] ErrorOr
|
2023-01-17 11:38:16 +02:00
|
|
|
{
|
|
|
|
public:
|
2023-02-22 01:23:11 +02:00
|
|
|
ErrorOr(const T& value)
|
|
|
|
: m_data(value)
|
|
|
|
{}
|
|
|
|
ErrorOr(T&& value)
|
|
|
|
: m_data(move(value))
|
|
|
|
{}
|
|
|
|
ErrorOr(const Error& error)
|
|
|
|
: m_data(error)
|
|
|
|
{}
|
|
|
|
ErrorOr(Error&& error)
|
|
|
|
: m_data(move(error))
|
|
|
|
{}
|
2023-01-17 11:38:16 +02:00
|
|
|
|
2023-04-18 18:29:48 +03:00
|
|
|
bool is_error() const { return m_data.template has<Error>(); }
|
2023-02-22 01:23:11 +02:00
|
|
|
const Error& error() const { return m_data.template get<Error>(); }
|
|
|
|
Error& error() { return m_data.template get<Error>(); }
|
|
|
|
const T& value() const { return m_data.template get<T>(); }
|
|
|
|
T& value() { return m_data.template get<T>(); }
|
2023-02-26 02:54:34 +02:00
|
|
|
|
2023-04-11 23:25:21 +03:00
|
|
|
Error release_error() { return move(error()); m_data.clear(); }
|
2023-02-22 01:23:11 +02:00
|
|
|
T release_value() { return move(value()); m_data.clear(); }
|
2023-01-17 11:38:16 +02:00
|
|
|
|
|
|
|
private:
|
2023-02-22 01:23:11 +02:00
|
|
|
Variant<Error, T> m_data;
|
2023-01-17 11:38:16 +02:00
|
|
|
};
|
|
|
|
|
2023-04-18 22:02:47 +03:00
|
|
|
template<lvalue_reference T>
|
|
|
|
class [[nodiscard]] ErrorOr<T>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ErrorOr(T value)
|
|
|
|
{
|
|
|
|
m_data.template set<T>(value);
|
|
|
|
}
|
|
|
|
ErrorOr(Error&& error)
|
|
|
|
: m_data(move(error))
|
|
|
|
{ }
|
|
|
|
ErrorOr(const Error& error)
|
|
|
|
: m_data(error)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
bool is_error() const { return m_data.template has<Error>(); }
|
|
|
|
Error& error() { return m_data.template get<Error>(); }
|
|
|
|
const Error& error() const { return m_data.template get<Error>(); }
|
|
|
|
T value() { return m_data.template get<T>(); }
|
|
|
|
|
|
|
|
Error release_error() { return move(error()); m_data.clear(); }
|
|
|
|
T release_value() { return value(); m_data.clear(); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
Variant<Error, T> m_data;
|
|
|
|
};
|
|
|
|
|
2023-01-17 11:38:16 +02:00
|
|
|
template<>
|
2023-02-19 20:10:30 +02:00
|
|
|
class [[nodiscard]] ErrorOr<void>
|
2023-01-17 11:38:16 +02:00
|
|
|
{
|
|
|
|
public:
|
2023-02-22 01:23:11 +02:00
|
|
|
ErrorOr() {}
|
|
|
|
ErrorOr(const Error& error) : m_data(error), m_has_error(true) {}
|
|
|
|
ErrorOr(Error&& error) : m_data(move(error)), m_has_error(true) {}
|
2022-12-13 10:39:57 +02:00
|
|
|
|
2023-02-01 21:05:44 +02:00
|
|
|
bool is_error() const { return m_has_error; }
|
2023-02-22 01:23:11 +02:00
|
|
|
Error& error() { return m_data; }
|
|
|
|
const Error& error() const { return m_data; }
|
2023-02-01 21:05:44 +02:00
|
|
|
void value() { }
|
2023-02-26 02:54:34 +02:00
|
|
|
|
2023-04-11 23:25:21 +03:00
|
|
|
Error release_error() { return move(m_data); }
|
|
|
|
void release_value() { }
|
2022-12-13 10:39:57 +02:00
|
|
|
|
2023-01-17 11:38:16 +02:00
|
|
|
private:
|
2023-05-22 19:54:59 +03:00
|
|
|
Error m_data { Error::from_errno(0) };
|
2023-04-11 23:25:21 +03:00
|
|
|
bool m_has_error { false };
|
2023-01-17 11:38:16 +02:00
|
|
|
};
|
2022-12-13 10:39:57 +02:00
|
|
|
|
2023-01-17 11:38:16 +02:00
|
|
|
}
|
2022-12-13 10:39:57 +02:00
|
|
|
|
|
|
|
namespace BAN::Formatter
|
|
|
|
{
|
2022-12-27 19:55:07 +02:00
|
|
|
template<typename F>
|
2023-04-11 23:25:21 +03:00
|
|
|
void print_argument(F putc, const Error& error, const ValueFormat& format)
|
2022-12-13 10:39:57 +02:00
|
|
|
{
|
2023-04-11 23:25:21 +03:00
|
|
|
print_argument(putc, error.get_message(), format);
|
2022-12-13 10:39:57 +02:00
|
|
|
}
|
2023-01-17 11:38:16 +02:00
|
|
|
}
|