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