pw_status: Introduce pw::OkStatus()

Status::Ok() is too similar to Status::ok(); having both status.ok() and
status.Ok() compile but mean different things is confusing.

This CL introduces a pw::OkStatus() free function that is an alias for
pw::Status(). This is intended to be a concise, readable way to create
a status with code PW_STATUS_OK.

Change-Id: I85d2ea1d14662c6c4d455219cfeced90c5f92218
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/28900
Reviewed-by: Ewout van Bekkum <ewout@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
diff --git a/pw_status/docs.rst b/pw_status/docs.rst
index a2de75f..0f01ea8 100644
--- a/pw_status/docs.rst
+++ b/pw_status/docs.rst
@@ -20,26 +20,31 @@
 ) and `gRPC <https://grpc.io>`_ (`doc/statuscodes.md
 <https://github.com/grpc/grpc/blob/master/doc/statuscodes.md>`_).
 
-A ``Status`` is created with a ``static constexpr`` member function
-corresponding to the code.
+An OK ``Status`` is created by the ``pw::OkStatus`` function or by the default
+``Status`` constructor.  Non-OK ``Status`` is created with a static member
+function that corresponds with the status code.
 
 .. code-block:: cpp
 
   // Ok (gRPC code "OK") does not indicate an error; this value is returned on
   // success. It is typical to check for this value before proceeding on any
   // given call across an API or RPC boundary. To check this value, use the
-  // `Status::ok()` member function rather than inspecting the raw code.
-  Status::Ok()
+  // `status.ok()` member function rather than inspecting the raw code.
+  //
+  // OkStatus() is provided as a free function, rather than a static member
+  // function like the error statuses to avoid conflicts with the ok() member
+  // function. Status::Ok() would be too similar to Status::ok().
+  pw::OkStatus()
 
   // Cancelled (gRPC code "CANCELLED") indicates the operation was cancelled,
   // typically by the caller.
-  Status::Cancelled()
+  pw::Status::Cancelled()
 
   // Unknown (gRPC code "UNKNOWN") indicates an unknown error occurred. In
   // general, more specific errors should be raised, if possible. Errors raised
   // by APIs that do not return enough error information may be converted to
   // this error.
-  Status::Unknown()
+  pw::Status::Unknown()
 
   // InvalidArgument (gRPC code "INVALID_ARGUMENT") indicates the caller
   // specified an invalid argument, such a malformed filename. Note that such
@@ -47,14 +52,14 @@
   // arguments themselves. Errors with validly formed arguments that may cause
   // errors with the state of the receiving system should be denoted with
   // `FailedPrecondition` instead.
-  Status::InvalidArgument()
+  pw::Status::InvalidArgument()
 
   // DeadlineExceeded (gRPC code "DEADLINE_EXCEEDED") indicates a deadline
   // expired before the operation could complete. For operations that may change
   // state within a system, this error may be returned even if the operation has
   // completed successfully. For example, a successful response from a server
   // could have been delayed long enough for the deadline to expire.
-  Status::DeadlineExceeded()
+  pw::Status::DeadlineExceeded()
 
   // NotFound (gRPC code "NOT_FOUND") indicates some requested entity (such as
   // a file or directory) was not found.
@@ -63,11 +68,11 @@
   // users, such as during a gradual feature rollout or undocumented allow list.
   // If, instead, a request should be denied for specific sets of users, such as
   // through user-based access control, use `PermissionDenied` instead.
-  Status::NotFound()
+  pw::Status::NotFound()
 
   // AlreadyExists (gRPC code "ALREADY_EXISTS") indicates the entity that a
   // caller attempted to create (such as file or directory) is already present.
-  Status::AlreadyExists()
+  pw::Status::AlreadyExists()
 
   // PermissionDenied (gRPC code "PERMISSION_DENIED") indicates that the caller
   // does not have permission to execute the specified operation. Note that this
@@ -79,12 +84,12 @@
   // some resource. Instead, use `ResourceExhausted` for those errors.
   // `PermissionDenied` must not be used if the caller cannot be identified.
   // Instead, use `Unauthenticated` for those errors.
-  Status::PermissionDenied()
+  pw::Status::PermissionDenied()
 
   // ResourceExhausted (gRPC code "RESOURCE_EXHAUSTED") indicates some resource
   // has been exhausted, perhaps a per-user quota, or perhaps the entire file
   // system is out of space.
-  Status::ResourceExhausted()
+  pw::Status::ResourceExhausted()
 
   // FailedPrecondition (gRPC code "FAILED_PRECONDITION") indicates that the
   // operation was rejected because the system is not in a state required for
@@ -103,7 +108,7 @@
   //      fails because the directory is non-empty, `FailedPrecondition`
   //      should be returned since the client should not retry unless
   //      the files are deleted from the directory.
-  Status::FailedPrecondition()
+  pw::Status::FailedPrecondition()
 
   // Aborted (gRPC code "ABORTED") indicates the operation was aborted,
   // typically due to a concurrency issue such as a sequencer check failure or a
@@ -111,7 +116,7 @@
   //
   // See the guidelines above for deciding between `FailedPrecondition`,
   // `Aborted`, and `Unavailable`.
-  Status::Aborted()
+  pw::Status::Aborted()
 
   // OutOfRange (gRPC code "OUT_OF_RANGE") indicates the operation was
   // attempted past the valid range, such as seeking or reading past an
@@ -129,17 +134,17 @@
   // error) when it applies so that callers who are iterating through
   // a space can easily look for an `OutOfRange` error to detect when
   // they are done.
-  Status::OutOfRange()
+  pw::Status::OutOfRange()
 
   // Unimplemented (gRPC code "UNIMPLEMENTED") indicates the operation is not
   // implemented or supported in this service. In this case, the operation
   // should not be re-attempted.
-  Status::Unimplemented()
+  pw::Status::Unimplemented()
 
   // Internal (gRPC code "INTERNAL") indicates an internal error has occurred
   // and some invariants expected by the underlying system have not been
   // satisfied. This error code is reserved for serious errors.
-  Status::Internal()
+  pw::Status::Internal()
 
   // Unavailable (gRPC code "UNAVAILABLE") indicates the service is currently
   // unavailable and that this is most likely a transient condition. An error
@@ -148,17 +153,17 @@
   //
   // See the guidelines above for deciding between `FailedPrecondition`,
   // `Aborted`, and `Unavailable`.
-  Status::Unavailable()
+  pw::Status::Unavailable()
 
   // DataLoss (gRPC code "DATA_LOSS") indicates that unrecoverable data loss or
   // corruption has occurred. As this error is serious, proper alerting should
   // be attached to errors such as this.
-  Status::DataLoss()
+  pw::Status::DataLoss()
 
   // Unauthenticated (gRPC code "UNAUTHENTICATED") indicates that the request
   // does not have valid authentication credentials for the operation. Correct
   // the authentication and try again.
-  Status::Unauthenticated()
+  pw::Status::Unauthenticated()
 
 .. attention::
 
@@ -199,7 +204,7 @@
   .. code-block:: cpp
 
     // An OK StatusWithSize with a size of 123.
-    StatusWithSize::Ok(123)
+    StatusWithSize(123)
 
     // A NOT_FOUND StatusWithSize with a size of 0.
     StatusWithSize::NotFound()
diff --git a/pw_status/public/pw_status/status.h b/pw_status/public/pw_status/status.h
index 2842797..f9227d7 100644
--- a/pw_status/public/pw_status/status.h
+++ b/pw_status/public/pw_status/status.h
@@ -32,7 +32,7 @@
   // success. It is typical to check for this value before proceeding on any
   // given call across an API or RPC boundary. To check this value, use the
   // `Status::ok()` member function rather than inspecting the raw code.
-  PW_STATUS_OK = 0,  // Use Status::Ok() in C++
+  PW_STATUS_OK = 0,  // Use OkStatus() in C++
 
   // Cancelled (gRPC code "CANCELLED") indicates the operation was cancelled,
   // typically by the caller.
@@ -215,14 +215,14 @@
 namespace pw {
 
 // The Status class is a thin, zero-cost abstraction around the pw_Status enum.
-// It initializes to Status::Ok() by default and adds ok() and str() methods.
+// It initializes to OkStatus() by default and adds ok() and str() methods.
 // Implicit conversions are permitted between pw_Status and pw::Status.
 class Status {
  public:
   using Code = pw_Status;
 
   // All of the pw_Status codes are available in the Status class as, e.g.
-  // pw::Status::Ok() or pw::Status::OutOfRange().
+  // pw::OkStatus() or pw::Status::OutOfRange().
   //
   // These aliases are DEPRECATED -- prefer using the helper functions below.
   // For example, change Status::CANCELLED to Status::Cancelled().
@@ -310,7 +310,7 @@
   // Returns the Status::Code (pw_Status) for this Status.
   constexpr Code code() const { return code_; }
 
-  // True if the status is Status::Ok().
+  // True if the status is OK.
   [[nodiscard]] constexpr bool ok() const { return code_ == PW_STATUS_OK; }
 
   // Functions for checking which status this is.
@@ -370,6 +370,11 @@
   Code code_;
 };
 
+// Returns an OK status. Equivalent to Status() or Status(PW_STATUS_OK). This
+// function is used instead of a Status::Ok() function, which would be too
+// similar to Status::ok().
+[[nodiscard]] constexpr Status OkStatus() { return Status(); }
+
 constexpr bool operator==(const Status& lhs, const Status& rhs) {
   return lhs.code() == rhs.code();
 }
diff --git a/pw_status/py/pw_status/update_style.py b/pw_status/py/pw_status/update_style.py
index 4e67941..ff59115 100755
--- a/pw_status/py/pw_status/update_style.py
+++ b/pw_status/py/pw_status/update_style.py
@@ -26,7 +26,6 @@
 from pw_presubmit import git_repo
 
 _REMAP = {
-    'OK': 'Ok',
     'CANCELLED': 'Cancelled',
     'UNKNOWN': 'Unknown',
     'INVALID_ARGUMENT': 'InvalidArgument',
@@ -62,6 +61,9 @@
 
 def _remap_codes(match) -> bytes:
     status, code = (g.decode() for g in match.groups())
+    if status == 'OK':
+        return b'OkStatus()'
+
     return f'{status}::{_REMAP[code]}()'.encode()
 
 
diff --git a/pw_status/status_test.cc b/pw_status/status_test.cc
index 4812b9d..eb45758 100644
--- a/pw_status/status_test.cc
+++ b/pw_status/status_test.cc
@@ -61,7 +61,7 @@
 TEST(Status, Ok_OkIsTrue) {
   static_assert(Status().ok());
   static_assert(Status(PW_STATUS_OK).ok());
-  static_assert(Status::Ok().ok());
+  static_assert(OkStatus().ok());
 }
 
 TEST(Status, NotOk_OkIsFalse) {
@@ -72,7 +72,7 @@
 TEST(Status, Code) {
   // clang-format off
   static_assert(PW_STATUS_OK == Status().code());
-  static_assert(PW_STATUS_OK == Status::Ok().code());
+  static_assert(PW_STATUS_OK == OkStatus().code());
   static_assert(PW_STATUS_CANCELLED == Status::Cancelled().code());
   static_assert(PW_STATUS_UNKNOWN == Status::Unknown().code());
   static_assert(PW_STATUS_INVALID_ARGUMENT == Status::InvalidArgument().code());
@@ -94,7 +94,7 @@
 
 TEST(Status, EqualCodes) {
   static_assert(PW_STATUS_OK == Status());
-  static_assert(PW_STATUS_OK == Status::Ok());
+  static_assert(PW_STATUS_OK == OkStatus());
   static_assert(PW_STATUS_CANCELLED == Status::Cancelled());
   static_assert(PW_STATUS_UNKNOWN == Status::Unknown());
   static_assert(PW_STATUS_INVALID_ARGUMENT == Status::InvalidArgument());
@@ -133,27 +133,27 @@
 }
 
 TEST(Status, IsNotError) {
-  static_assert(!Status::Ok().IsCancelled());
-  static_assert(!Status::Ok().IsUnknown());
-  static_assert(!Status::Ok().IsInvalidArgument());
-  static_assert(!Status::Ok().IsDeadlineExceeded());
-  static_assert(!Status::Ok().IsNotFound());
-  static_assert(!Status::Ok().IsAlreadyExists());
-  static_assert(!Status::Ok().IsPermissionDenied());
-  static_assert(!Status::Ok().IsUnauthenticated());
-  static_assert(!Status::Ok().IsResourceExhausted());
-  static_assert(!Status::Ok().IsFailedPrecondition());
-  static_assert(!Status::Ok().IsAborted());
-  static_assert(!Status::Ok().IsOutOfRange());
-  static_assert(!Status::Ok().IsUnimplemented());
-  static_assert(!Status::Ok().IsInternal());
-  static_assert(!Status::Ok().IsUnavailable());
-  static_assert(!Status::Ok().IsDataLoss());
+  static_assert(!OkStatus().IsCancelled());
+  static_assert(!OkStatus().IsUnknown());
+  static_assert(!OkStatus().IsInvalidArgument());
+  static_assert(!OkStatus().IsDeadlineExceeded());
+  static_assert(!OkStatus().IsNotFound());
+  static_assert(!OkStatus().IsAlreadyExists());
+  static_assert(!OkStatus().IsPermissionDenied());
+  static_assert(!OkStatus().IsUnauthenticated());
+  static_assert(!OkStatus().IsResourceExhausted());
+  static_assert(!OkStatus().IsFailedPrecondition());
+  static_assert(!OkStatus().IsAborted());
+  static_assert(!OkStatus().IsOutOfRange());
+  static_assert(!OkStatus().IsUnimplemented());
+  static_assert(!OkStatus().IsInternal());
+  static_assert(!OkStatus().IsUnavailable());
+  static_assert(!OkStatus().IsDataLoss());
 }
 
 TEST(Status, Strings) {
   EXPECT_STREQ("OK", Status().str());
-  EXPECT_STREQ("OK", Status::Ok().str());
+  EXPECT_STREQ("OK", OkStatus().str());
   EXPECT_STREQ("CANCELLED", Status::Cancelled().str());
   EXPECT_STREQ("UNKNOWN", Status::Unknown().str());
   EXPECT_STREQ("INVALID_ARGUMENT", Status::InvalidArgument().str());
@@ -215,7 +215,7 @@
   EXPECT_EQ(Status::Unknown(), PassStatusFromC(Status::Unknown()));
 
   EXPECT_EQ(Status::NotFound(), PassStatusFromC(PW_STATUS_NOT_FOUND));
-  EXPECT_EQ(Status::Ok(), PassStatusFromC(Status::Ok()));
+  EXPECT_EQ(OkStatus(), PassStatusFromC(OkStatus()));
 }
 
 TEST(StatusCLinkage, TestStatusFromC) { EXPECT_EQ(0, TestStatusFromC()); }