1.. _module-pw_status-guide: 2 3==================== 4Get started & guides 5==================== 6.. pigweed-module-subpage:: 7 :name: pw_status 8 9.. _module-pw_status-get-started: 10 11----------- 12Get started 13----------- 14To deploy ``pw_status``, depend on the library: 15 16.. tab-set:: 17 18 .. tab-item:: Bazel 19 20 Add ``@pigweed//pw_status`` to the ``deps`` list in your Bazel target: 21 22 .. code-block:: 23 24 cc_library("...") { 25 # ... 26 deps = [ 27 # ... 28 "@pigweed//pw_status", 29 # ... 30 ] 31 } 32 33 This assumes that your Bazel ``WORKSPACE`` has a `repository 34 <https://bazel.build/concepts/build-ref#repositories>`_ named ``@pigweed`` 35 that points to the upstream Pigweed repository. 36 37 .. tab-item:: GN 38 39 Add ``$dir_pw_status`` to the ``deps`` list in your ``pw_executable()`` 40 build target: 41 42 .. code-block:: 43 44 pw_executable("...") { 45 # ... 46 deps = [ 47 # ... 48 "$dir_pw_status", 49 # ... 50 ] 51 } 52 53 .. tab-item:: CMake 54 55 Add ``pw_status`` to your ``pw_add_library`` or similar CMake target: 56 57 .. code-block:: 58 59 pw_add_library(my_library STATIC 60 HEADERS 61 ... 62 PRIVATE_DEPS 63 # ... 64 pw_status 65 # ... 66 ) 67 68 .. tab-item:: Zephyr 69 70 There are two ways to use ``pw_status`` from a Zephyr project: 71 72 * Depend on ``pw_status`` in your CMake target (see CMake tab). This is 73 the Pigweed team's suggested approach since it enables precise CMake 74 dependency analysis. 75 76 * Add ``CONFIG_PIGWEED_STATUS=y`` to the Zephyr project's configuration, 77 which causes ``pw_status`` to become a global dependency and have the 78 includes exposed to all targets. The Pigweed team does not recommend 79 this approach, though it is the typical Zephyr solution. 80 81Then use the status object or try macros: 82 83.. code-block:: cpp 84 85 #include "pw_status/try.h" 86 #include "pw_status/status.h" 87 88 pw::Status MyOperation() { 89 PW_TRY(SubOp1()); 90 PW_TRY(SubOp2()); 91 // ... 92 return pw::OkStatus(); 93 } 94 95------ 96Guides 97------ 98 99Tracking the first error encountered 100------------------------------------ 101In some contexts it is useful to track the first error encountered while 102allowing execution to continue. Manually writing out ``if`` statements to check 103and then assign quickly becomes verbose, and doesn't explicitly highlight the 104intended behavior of "latching" to the first error. 105 106.. admonition:: **No**: Track status manually across calls 107 :class: error 108 109 .. code-block:: cpp 110 111 Status overall_status; 112 for (Sector& sector : sectors) { 113 Status erase_status = sector.Erase(); 114 if (!overall_status.ok()) { 115 overall_status = erase_status; 116 } 117 118 if (erase_status.ok()) { 119 Status header_write_status = sector.WriteHeader(); 120 if (!overall_status.ok()) { 121 overall_status = header_write_status; 122 } 123 } 124 } 125 return overall_status; 126 127:cpp:class:`pw::Status` has a :cpp:func:`pw::Status::Update()` helper function 128that does exactly this to reduce visual clutter and succinctly highlight the 129intended behavior. 130 131.. admonition:: **Yes**: Track status with :cpp:func:`pw::Status::Update()` 132 :class: checkmark 133 134 .. code-block:: cpp 135 136 Status overall_status; 137 for (Sector& sector : sectors) { 138 Status erase_status = sector.Erase(); 139 overall_status.Update(erase_status); 140 141 if (erase_status.ok()) { 142 overall_status.Update(sector.WriteHeader()); 143 } 144 } 145 return overall_status; 146 147.. _module-pw_status-guide-status-with-size: 148 149---------------------------------- 150Jointly reporting status with size 151---------------------------------- 152``pw::StatusWithSize`` (``pw_status/status_with_size.h``) is a convenient, 153efficient class for reporting a status along with an unsigned integer value. 154It is similar to the ``pw::Result<T>`` class, but it stores both a size and a 155status, regardless of the status value, and only supports a limited range (27 156bits). 157 158``pw::StatusWithSize`` values may be created with functions similar to 159``pw::Status``. For example: 160 161.. code-block:: cpp 162 163 #include "pw_status/status_with_size.h" 164 165 // An OK StatusWithSize with a size of 123. 166 StatusWithSize(123) 167 168 // A NOT_FOUND StatusWithSize with a size of 0. 169 StatusWithSize::NotFound() 170 171 // A RESOURCE_EXHAUSTED StatusWithSize with a size of 10. 172 StatusWithSize::ResourceExhausted(10) 173 174``pw::StatusWithSize`` is useful for cases where an operation may partially 175complete - for example read operations may read some number of bytes into an 176output buffer, but not all. 177 178----------------------------------- 179Reducing error handling boilerplate 180----------------------------------- 181Manual error handling through return codes is easy to understand and 182straightforward to write, but leads to verbose code. To reduce boilerplate, 183Pigweed has the ``PW_TRY`` (``pw_status/try.h``) macro, easing development of 184functions checking or returning ``pw::Status`` and ``pw::StatusWithSize`` 185objects. The ``PW_TRY`` and ``PW_TRY_WITH_SIZE`` macros call a function and do 186an early return if the function's return status is not :c:enumerator:`OK`. 187 188Example: 189 190.. code-block:: cpp 191 192 Status PwTryExample() { 193 PW_TRY(FunctionThatReturnsStatus()); 194 PW_TRY(FunctionThatReturnsStatusWithSize()); 195 196 // Do something, only executed if both functions above return OK. 197 } 198 199 StatusWithSize PwTryWithSizeExample() { 200 PW_TRY_WITH_SIZE(FunctionThatReturnsStatus()); 201 PW_TRY_WITH_SIZE(FunctionThatReturnsStatusWithSize()); 202 203 // Do something, only executed if both functions above return OK. 204 } 205 206``PW_TRY_ASSIGN`` is for working with ``pw::StatusWithSize`` objects in in 207functions that return Status. It is similar to ``PW_TRY`` with the addition of 208assigning the size from the ``pw::StatusWithSize`` on ok. 209 210.. code-block:: cpp 211 212 Status PwTryAssignExample() { 213 size_t size_value 214 PW_TRY_ASSIGN(size_value, FunctionThatReturnsStatusWithSize()); 215 216 // Do something that uses size_value. size_value is only assigned and this 217 // following code executed if the PW_TRY_ASSIGN function above returns OK. 218 } 219