pw_status: Add Update()
Adds an Abseil-style Update() helper to pw::Status that makes it easier
to track the first error encountered by a Status object.
Change-Id: I0aaca4c49e68daa578c8a39ffce726ae0c6dc5b3
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/42620
Pigweed-Auto-Submit: Armando Montanez <amontanez@google.com>
Reviewed-by: Wyatt Hepler <hepler@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
diff --git a/pw_status/docs.rst b/pw_status/docs.rst
index 0f01ea8..c2595c5 100644
--- a/pw_status/docs.rst
+++ b/pw_status/docs.rst
@@ -179,6 +179,47 @@
The Python tool ``pw_status/update_style.py`` may be used to migrate code in a
Git repo to the new status style.
+Tracking the first error encountered
+------------------------------------
+In some contexts it is useful to track the first error encountered while
+allowing execution to continue. Manually writing out ``if`` statements to check
+and then assign quickly becomes verbose, and doesn't explicitly highlight the
+intended behavior of "latching" to the first error.
+
+ .. code-block:: cpp
+
+ Status overall_status;
+ for (Sector& sector : sectors) {
+ Status erase_status = sector.Erase();
+ if (!overall_status.ok()) {
+ overall_status = erase_status;
+ }
+
+ if (erase_status.ok()) {
+ Status header_write_status = sector.WriteHeader();
+ if (!overall_status.ok()) {
+ overall_status = header_write_status;
+ }
+ }
+ }
+ return overall_status;
+
+``pw::Status`` has an ``Update()`` helper function that does exactly this to
+reduce visual clutter and succinctly highlight the intended behavior.
+
+ .. code-block:: cpp
+
+ Status overall_status;
+ for (Sector& sector : sectors) {
+ Status erase_status = sector.Erase();
+ overall_status.Update(erase_status);
+
+ if (erase_status.ok()) {
+ overall_status.Update(sector.WriteHeader());
+ }
+ }
+ return overall_status;
+
C compatibility
---------------
``pw_status`` provides the C-compatible ``pw_Status`` enum for the status codes.
diff --git a/pw_status/public/pw_status/status.h b/pw_status/public/pw_status/status.h
index ae3b852..eb02440 100644
--- a/pw_status/public/pw_status/status.h
+++ b/pw_status/public/pw_status/status.h
@@ -303,6 +303,15 @@
return code_ == PW_STATUS_UNAUTHENTICATED;
}
+ // Updates this Status to the provided Status IF this status is OK. This is
+ // useful for tracking the first encountered error, as calls to this helper
+ // will not change one error status to another error status.
+ constexpr void Update(Status other) {
+ if (ok()) {
+ code_ = other.code();
+ }
+ }
+
// Returns a null-terminated string representation of the Status.
[[nodiscard]] const char* str() const { return pw_StatusString(code_); }
diff --git a/pw_status/status_test.cc b/pw_status/status_test.cc
index 0bf72f5..33102b7 100644
--- a/pw_status/status_test.cc
+++ b/pw_status/status_test.cc
@@ -156,6 +156,16 @@
EXPECT_STREQ("INVALID STATUS", Status(kInvalidCode).str());
}
+TEST(Status, Update) {
+ Status status;
+ status.Update(Status::Cancelled());
+ EXPECT_EQ(status, Status::Cancelled());
+ status.Update(OkStatus());
+ EXPECT_EQ(status, Status::Cancelled());
+ status.Update(Status::NotFound());
+ EXPECT_EQ(status, Status::Cancelled());
+}
+
// Functions for executing the C pw_Status tests.
extern "C" {