[promises] Add some niceties for StatusFlag, ValueOrFailure

PiperOrigin-RevId: 586804010
pull/35155/head
Craig Tiller 1 year ago committed by Copybara-Service
parent ff4058a738
commit e348d65bc7
  1. 38
      src/core/lib/promise/status_flag.h
  2. 2
      test/core/promise/status_flag_test.cc

@ -25,11 +25,31 @@
namespace grpc_core {
struct Failure {};
struct Success {};
inline bool IsStatusOk(Failure) { return false; }
inline bool IsStatusOk(Success) { return true; }
template <>
struct StatusCastImpl<absl::Status, Success> {
static absl::Status Cast(Success) { return absl::OkStatus(); }
};
template <>
struct StatusCastImpl<absl::Status, const Success&> {
static absl::Status Cast(Success) { return absl::OkStatus(); }
};
// A boolean representing whether an operation succeeded (true) or failed
// (false).
class StatusFlag {
public:
explicit StatusFlag(bool value) : value_(value) {}
// NOLINTNEXTLINE(google-explicit-constructor)
StatusFlag(Failure) : value_(false) {}
// NOLINTNEXTLINE(google-explicit-constructor)
StatusFlag(Success) : value_(true) {}
bool ok() const { return value_; }
@ -46,14 +66,21 @@ struct StatusCastImpl<absl::Status, StatusFlag> {
}
};
struct Failure {};
template <>
struct StatusCastImpl<absl::Status, const StatusFlag&> {
static absl::Status Cast(StatusFlag flag) {
return flag.ok() ? absl::OkStatus() : absl::CancelledError();
}
};
// A value if an operation was successful, or a failure flag if not.
template <typename T>
class ValueOrFailure {
public:
explicit ValueOrFailure(T value) : value_(std::move(value)) {}
explicit ValueOrFailure(Failure) {}
// NOLINTNEXTLINE(google-explicit-constructor)
ValueOrFailure(T value) : value_(std::move(value)) {}
// NOLINTNEXTLINE(google-explicit-constructor)
ValueOrFailure(Failure) {}
static ValueOrFailure FromOptional(absl::optional<T> value) {
return ValueOrFailure{std::move(value)};
@ -75,6 +102,11 @@ inline bool IsStatusOk(const ValueOrFailure<T>& value) {
return value.ok();
}
template <typename T>
inline T TakeValue(ValueOrFailure<T>&& value) {
return std::move(value.value());
}
template <typename T>
struct StatusCastImpl<absl::Status, ValueOrFailure<T>> {
static absl::Status Cast(const ValueOrFailure<T> flag) {

@ -33,6 +33,8 @@ TEST(StatusFlagTest, Basics) {
EXPECT_EQ(ValueOrFailure<int>(42).value(), 42);
EXPECT_EQ(StatusCast<absl::StatusOr<int>>(ValueOrFailure<int>(42)).value(),
42);
EXPECT_TRUE(IsStatusOk(Success{}));
EXPECT_FALSE(IsStatusOk(Failure{}));
}
} // namespace grpc_core

Loading…
Cancel
Save