[promises] Add some niceties for StatusFlag, ValueOrFailure
PiperOrigin-RevId: 586804010
diff --git a/src/core/lib/promise/status_flag.h b/src/core/lib/promise/status_flag.h
index 063cb76..54019d3 100644
--- a/src/core/lib/promise/status_flag.h
+++ b/src/core/lib/promise/status_flag.h
@@ -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 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)};
@@ -76,6 +103,11 @@
}
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) {
return flag.ok() ? absl::OkStatus() : absl::CancelledError();
diff --git a/test/core/promise/status_flag_test.cc b/test/core/promise/status_flag_test.cc
index 799a089..dcde364 100644
--- a/test/core/promise/status_flag_test.cc
+++ b/test/core/promise/status_flag_test.cc
@@ -33,6 +33,8 @@
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