added result class
This commit is contained in:
parent
1fe5c9bac4
commit
b7c12d8217
|
|
@ -12,7 +12,7 @@ list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras)
|
||||||
include(CTest)
|
include(CTest)
|
||||||
include(Catch)
|
include(Catch)
|
||||||
|
|
||||||
set(POSTGRES_CONNECTION_STRING "postgres://test:test123@127.0.0.1:15432/test")
|
set(POSTGRES_CONNECTION_STRING "postgres://test:test123@127.0.0.1:5432/matador_test")
|
||||||
|
|
||||||
configure_file(Connection.hpp.in ${PROJECT_BINARY_DIR}/backends/postgres/test/connection.hpp @ONLY IMMEDIATE)
|
configure_file(Connection.hpp.in ${PROJECT_BINARY_DIR}/backends/postgres/test/connection.hpp @ONLY IMMEDIATE)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
#ifndef QUERY_RESULT_HPP
|
||||||
|
#define QUERY_RESULT_HPP
|
||||||
|
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
|
namespace matador::utils {
|
||||||
|
|
||||||
|
template < typename ValueType, typename ErrorType >
|
||||||
|
class [[nodiscard]] result;
|
||||||
|
|
||||||
|
template <typename ValueType>
|
||||||
|
struct is_result : std::false_type {};
|
||||||
|
|
||||||
|
template < typename ValueType, typename ErrorType >
|
||||||
|
struct is_result<result<ValueType, ErrorType>> : std::true_type {};
|
||||||
|
|
||||||
|
template < typename ValueType >
|
||||||
|
class ok
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit constexpr ok(const ValueType &value) : value_(value) {}
|
||||||
|
explicit constexpr ok(ValueType &&value) : value_(std::move(value)) {}
|
||||||
|
|
||||||
|
constexpr ValueType&& release() { return std::move(value_); }
|
||||||
|
const ValueType& value() const { return value_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ValueType value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template < typename ErrorType >
|
||||||
|
class error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit constexpr error(const ErrorType &error) : error_(error) {}
|
||||||
|
explicit constexpr error(ErrorType &&error) : error_(std::move(error)) {}
|
||||||
|
|
||||||
|
constexpr ErrorType&& release() { return std::move(error_); }
|
||||||
|
const ErrorType& value() const { return error_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ErrorType error_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template < typename ValueType, typename ErrorType >
|
||||||
|
class result
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using value_type = ok<ValueType>;
|
||||||
|
using error_type = error<ErrorType>;
|
||||||
|
|
||||||
|
result(value_type value) : result_(value) {} // NOLINT(*-explicit-constructor)
|
||||||
|
result(error_type error) : result_(error) {} // NOLINT(*-explicit-constructor)
|
||||||
|
|
||||||
|
operator bool() const { return is_ok(); } // NOLINT(*-explicit-constructor)
|
||||||
|
|
||||||
|
[[nodiscard]] bool is_ok() const { return std::holds_alternative<value_type>(result_); }
|
||||||
|
[[nodiscard]] bool is_error() const { return std::holds_alternative<error_type>(result_); }
|
||||||
|
|
||||||
|
ValueType&& release() { return std::get<value_type>(result_).release(); }
|
||||||
|
ErrorType&& release_error() { return std::get<error_type>(result_).release(); }
|
||||||
|
|
||||||
|
const ValueType& value() const { return std::get<value_type>(result_).value(); }
|
||||||
|
const ErrorType& err() const { return std::get<error_type>(result_).value(); }
|
||||||
|
ErrorType err() { return std::get<error_type>(result_).value(); }
|
||||||
|
|
||||||
|
constexpr const ValueType* operator->() const { return &value(); }
|
||||||
|
constexpr ValueType* operator->() { return &value(); }
|
||||||
|
|
||||||
|
template<typename SecondValueType, typename SecondErrorType, typename Func>
|
||||||
|
result<SecondValueType, SecondErrorType> and_then(Func f) {
|
||||||
|
if (is_ok()) {
|
||||||
|
return f(value());
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::variant<value_type, error_type> result_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //QUERY_RESULT_HPP
|
||||||
|
|
@ -111,6 +111,7 @@ set(UTILS_HEADER
|
||||||
../include/matador/utils/types.hpp
|
../include/matador/utils/types.hpp
|
||||||
../include/matador/utils/foreign_attributes.hpp
|
../include/matador/utils/foreign_attributes.hpp
|
||||||
../include/matador/utils/fetch_type.hpp
|
../include/matador/utils/fetch_type.hpp
|
||||||
|
../include/matador/utils/result.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(UTILS_SOURCES
|
set(UTILS_SOURCES
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,8 @@ add_executable(tests
|
||||||
models/book.hpp
|
models/book.hpp
|
||||||
FieldTest.cpp
|
FieldTest.cpp
|
||||||
models/recipe.hpp
|
models/recipe.hpp
|
||||||
ValueTest.cpp)
|
ValueTest.cpp
|
||||||
|
ResultTest.cpp)
|
||||||
|
|
||||||
target_link_libraries(tests PRIVATE
|
target_link_libraries(tests PRIVATE
|
||||||
Catch2::Catch2WithMain
|
Catch2::Catch2WithMain
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
#include "matador/utils/result.hpp"
|
||||||
|
|
||||||
|
namespace matador::test {
|
||||||
|
|
||||||
|
enum class math_error : int32_t {
|
||||||
|
DIVISION_BY_ZERO = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
utils::result<float, math_error>divide(int x, int y) {
|
||||||
|
if (y == 0) {
|
||||||
|
return utils::error(math_error::DIVISION_BY_ZERO);
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils::ok(float(x) / y);
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::result<float, math_error>multiply(int x, int y) {
|
||||||
|
return utils::ok(float(x) * y);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace matador;
|
||||||
|
|
||||||
|
TEST_CASE("Result tests", "[result]") {
|
||||||
|
auto res = test::divide(4, 2);
|
||||||
|
REQUIRE(res);
|
||||||
|
REQUIRE(res.is_ok());
|
||||||
|
REQUIRE(!res.is_error());
|
||||||
|
|
||||||
|
REQUIRE((res.value() == 2.0));
|
||||||
|
|
||||||
|
REQUIRE_THROWS(res.err());
|
||||||
|
|
||||||
|
res = test::divide(4, 0);
|
||||||
|
REQUIRE(!res);
|
||||||
|
REQUIRE(!res.is_ok());
|
||||||
|
REQUIRE(res.is_error());
|
||||||
|
|
||||||
|
REQUIRE((res.err() == test::math_error::DIVISION_BY_ZERO));
|
||||||
|
|
||||||
|
|
||||||
|
// res = test::divide(4, 2)
|
||||||
|
// .and_then<>()
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue