60 lines
1.5 KiB
C++
60 lines
1.5 KiB
C++
//
|
|
// Created by erki on 16/01/24.
|
|
//
|
|
|
|
#pragma once
|
|
|
|
#include <expected>
|
|
#include <source_location>
|
|
#include <string_view>
|
|
#include <functional>
|
|
#include <utility>
|
|
|
|
#include <esp_err.h>
|
|
#include <esp_rom_sys.h>
|
|
|
|
#define TRY(x) ({ \
|
|
const auto& _x = (x); \
|
|
if (!_x) { \
|
|
return std::unexpected(_x.error()); \
|
|
} \
|
|
_x.value(); \
|
|
})
|
|
|
|
#define TRY_ESP(x) ({ \
|
|
const esp_err_t& _x = (x); \
|
|
if (_x != ESP_OK) \
|
|
return std::unexpected(_x); \
|
|
_x; \
|
|
})
|
|
|
|
[[noreturn]] inline void abortWithError(const char* error, const std::source_location location = std::source_location::current())
|
|
{
|
|
esp_rom_printf("abortWithError called, reason: %s\n", error);
|
|
esp_rom_printf("file: \"%s\" line %d\n", location.file_name(), location.line());
|
|
if (location.function_name() != nullptr)
|
|
esp_rom_printf("func: %s\n", location.function_name());
|
|
|
|
abort();
|
|
}
|
|
|
|
template<typename Expected>
|
|
decltype(auto) unwrapOrAbort(Expected&& expected, const std::source_location location = std::source_location::current())
|
|
{
|
|
if (!expected.has_value())
|
|
abortWithError("Unwrapped an errored expected.", location);
|
|
else
|
|
return std::forward<Expected>(expected).value();
|
|
}
|
|
|
|
template<typename Expected, typename F>
|
|
decltype(auto) unwrapOr(Expected&& expected, F&& f)
|
|
{
|
|
if (!expected.has_value())
|
|
std::invoke(std::forward<F>(f), expected.error());
|
|
else
|
|
return std::forward<Expected>(expected).value();
|
|
|
|
std::unreachable();
|
|
}
|