.. _module-pw_result:

=========
pw_result
=========
.. pigweed-module::
   :name: pw_result

   - **Easy**: Minimal boilerplate via with ``PW_TRY_ASSIGN`` macro and chaining
   - **Reliable**: Propagate errors consistently for less bugs
   - **Battle-tested**: Just like ``absl::StatusOr``, deployed extensively

``pw::Result<T>`` is a union of an error (:cpp:class:`pw::Status`) and a value
(``T``), in a type-safe and convenient wrapper. This enables operations to
return either a value on success, or an error code on failure, in one type.
Propagating errors with this one type is less burdensome than other methods,
reducing the temptation to write code that crashes or fails silently in error
cases. Take the following lengthy code for example:

.. code-block:: cpp

   #include "pw_log/log.h"
   #include "pw_result/result.h"
   #include "pw_status/try.h"

   pw::Result<int> GetBatteryVoltageMillivolts();  // Can fail

   pw::Status UpdateChargerDisplay() {
     const pw::Result<int> battery_mv = GetBatteryVoltageMillivolts();
     if (!battery_mv.ok()) {
       // Voltage read failed; propagate the status to callers.
       return battery_mv.status();
     }
     PW_LOG_INFO("Battery voltage: %d mV", *battery_mv);
     SetDisplayBatteryVoltage(*battery_mv);
     return pw::OkStatus();
   }

The ``PW_TRY_ASSIGN`` macro enables shortening the above to:

.. code-block:: cpp

   pw::Status UpdateChargerDisplay() {
     PW_TRY_ASSIGN(const int battery_mv, GetBatteryVoltageMillivolts());
     PW_LOG_INFO("Battery voltage: %d mV", *battery_mv);
     SetDisplayBatteryVoltage(*battery_mv);
     return pw::OkStatus();
   }

The ``pw::Result<T>`` class is based on Abseil's ``absl::StatusOr<T>`` class.
See Abseil's `documentation
<https://abseil.io/docs/cpp/guides/status#returning-a-status-or-a-value>`_ and
`usage tips <https://abseil.io/tips/181>`_ for extra guidance.

-----------
Get started
-----------
To deploy ``pw_result``, depend on the library:

.. tab-set::

   .. tab-item:: Bazel

      Add ``@pigweed//pw_result`` to the ``deps`` list in your Bazel target:

      .. code-block::

         cc_library("...") {
           # ...
           deps = [
             # ...
             "@pigweed//pw_result",
             # ...
           ]
         }

      This assumes that your Bazel ``WORKSPACE`` has a `repository
      <https://bazel.build/concepts/build-ref#repositories>`_ named ``@pigweed``
      that points to the upstream Pigweed repository.

   .. tab-item:: GN

      Add ``$dir_pw_result`` to the ``deps`` list in your ``pw_executable()``
      build target:

      .. code-block::

         pw_executable("...") {
           # ...
           deps = [
             # ...
             "$dir_pw_result",
             # ...
           ]
         }

   .. tab-item:: CMake

      Add ``pw_result`` to your ``pw_add_library`` or similar CMake target:

      .. code-block::

         pw_add_library(my_library STATIC
           HEADERS
             ...
           PRIVATE_DEPS
             # ...
             pw_result
             # ...
         )

   .. tab-item:: Zephyr

      There are two ways to use ``pw_result`` from a Zephyr project:

      * Depend on ``pw_result`` in your CMake target (see CMake tab). This is
        the Pigweed team's suggested approach since it enables precise CMake
        dependency analysis.

      * Add ``CONFIG_PIGWEED_RESULT=y`` to the Zephyr project's configuration,
        which causes ``pw_result`` to become a global dependency and have the
        includes exposed to all targets. The Pigweed team does not recommend
        this approach, though it is the typical Zephyr solution.

------
Guides
------

Overview
========
``pw::Result<T>`` objects represent either:

* A value (accessed with ``operator*`` or ``operator->``) and an OK status
* An error (accessed with ``.status()``) and no value

If ``result.ok()`` returns ``true`` the instance contains a valid value (of type
``T``). Otherwise, it does not contain a valid value, and attempting to access
the value is an error.

A ``pw::Result<T>`` instance can never contain both an OK status and a value. In
most cases, this is the appropriate choice. For cases where both a size and a
status must be returned, see :ref:`module-pw_status-guide-status-with-size`.

.. warning::

  Be careful not to use large value types in ``pw::Result`` objects, since they
  are embedded by value. This can quickly consume stack.

Returning a result from a function
==================================
To return a result from a function, return either a value (implicitly indicating
success), or a `non-OK pw::Status <module-pw_status-codes>` object otherwise (to
indicate failure).

.. code-block:: cpp

   pw::Result<float> GetAirPressureSensor() {
     uint32_t sensor_value;
     if (!vendor_raw_sensor_read(&sensor_value)) {
       return pw::Status::Unavailable();  // Converted to error Result
     }
     return sensor_value / 216.5;  // Converted to OK Result with float
   }

Accessing the contained value
=============================
Accessing the value held by a ``pw::Result<T>`` should be performed via
``operator*`` or ``operator->``, after a call to ``ok()`` has verified that the
value is present.

Accessing the value via ``operator->`` avoids introducing an extra local
variable to capture the result.

.. code-block:: cpp

   #include "pw_result/result.h"

   void Example() {
     if (pw::Result<Foo> foo = TryCreateFoo(); foo.ok()) {
       foo->DoBar();  // Note direct access to value inside the Result
     }
   }

Propagating errors from results
===============================
``pw::Result`` instances are compatible with the ``PW_TRY`` and
``PW_TRY_ASSIGN`` macros, which enable concise propagation of errors for
falliable operations that return values:

.. code-block:: cpp

   #include "pw_status/try.h"
   #include "pw_result/result.h"

   pw::Result<int> GetAnswer();  // Example function.

   pw::Status UseAnswerWithTry() {
     const pw::Result<int> answer = GetAnswer();
     PW_TRY(answer.status());
     if (answer.value() == 42) {
       WhatWasTheUltimateQuestion();
     }
     return pw::OkStatus();
   }

With the ``PW_TRY_ASSIGN`` macro, you can combine declaring the result with the
return:

.. code-block:: cpp

   pw::Status UseAnswerWithTryAssign() {
     PW_TRY_ASSIGN(const int answer, GetAnswer());
     PW_LOG_INFO("Got answer: %d", static_cast<int>(answer));
     return pw::OkStatus();
   }

Chaining results
================
``pw::Result<T>`` also supports chained operations, similar to the additions
made to ``std::optional<T>`` in C++23. These operations allow functions to be
applied to a ``pw::Result<T>`` that would perform additional computation.

These operations do not incur any additional FLASH or RAM cost compared to a
traditional if/else ladder, as can be seen in the `Code size analysis`_.

Without chaining or ``PW_TRY_ASSIGN``, invoking multiple falliable operations is
verbose:

.. code-block:: cpp

   pw::Result<Image> GetCuteCat(const Image& img) {
      pw::Result<Image> cropped = CropToCat(img);
      if (!cropped.ok()) {
        return cropped.status();
      }
      pw::Result<Image> with_tie = AddBowTie(*cropped);
      if (!with_tie.ok()) {
        return with_tie.status();
      }
      pw::Result<Image> with_sparkles = MakeEyesSparkle(*with_tie);
      if (!with_sparkles.ok()) {
        return with_parkes.status();
      }
      return AddRainbow(MakeSmaller(*with_sparkles));
   }

Leveraging ``PW_TRY_ASSIGN`` reduces the verbosity:

.. code-block:: cpp

   // Without chaining but using PW_TRY_ASSIGN.
   pw::Result<Image> GetCuteCat(const Image& img) {
      PW_TRY_ASSIGN(Image cropped, CropToCat(img));
      PW_TRY_ASSIGN(Image with_tie, AddBowTie(*cropped));
      PW_TRY_ASSIGN(Image with_sparkles, MakeEyesSparkle(*with_tie));
      return AddRainbow(MakeSmaller(*with_sparkles));
   }

With chaining we can reduce the code even further:

.. code-block:: cpp

   pw::Result<Image> GetCuteCat(const Image& img) {
     return CropToCat(img)
            .and_then(AddBoeTie)
            .and_then(MakeEyesSparkle)
            .transform(MakeSmaller)
            .transform(AddRainbow);
   }

``pw::Result<T>::and_then``
---------------------------
The ``pw::Result<T>::and_then`` member function will return the result of the
invocation of the provided function on the contained value if it exists.
Otherwise, returns the contained status in a ``pw::Result<U>``, which is the
return type of provided function.

.. code-block:: cpp

   // Expositional prototype of and_then:
   template <typename T>
   class Result {
     template <typename U>
     Result<U> and_then(Function<Result<U>(T)> func);
   };

   Result<Foo> CreateFoo();
   Result<Bar> CreateBarFromFoo(const Foo& foo);

   Result<Bar> bar = CreateFoo().and_then(CreateBarFromFoo);

``pw::Result<T>::or_else``
--------------------------
The ``pw::Result<T>::or_else`` member function will return ``*this`` if it
contains a value. Otherwise, it will return the result of the provided function.
The function must return a type convertible to a ``pw::Result<T>`` or ``void``.
This is particularly useful for handling errors.

.. code-block:: cpp

   // Expositional prototype of or_else:
   template <typename T>
   class Result {
     template <typename U>
       requires std::is_convertible_v<U, Result<T>>
     Result<T> or_else(Function<U(Status)> func);

     Result<T> or_else(Function<void(Status)> func);
   };

   // Without or_else:
   Result<Image> GetCuteCat(const Image& image) {
     Result<Image> cropped = CropToCat(image);
     if (!cropped.ok()) {
       PW_LOG_ERROR("Failed to crop cat: %d", cropped.status().code());
       return cropped.status();
     }
     return cropped;
   }

   // With or_else:
   Result<Image> GetCuteCat(const Image& image) {
     return CropToCat(image).or_else(
         [](Status s) { PW_LOG_ERROR("Failed to crop cat: %d", s.code()); });
   }

Another useful scenario for ``pw::Result<T>::or_else`` is providing a default
value that is expensive to compute. Typically, default values are provided by
using ``pw::Result<T>::value_or``, but that requires the default value to be
constructed regardless of whether you actually need it.

.. code-block:: cpp

   // With value_or:
   Image GetCuteCat(const Image& image) {
     // GenerateCuteCat() must execute regardless of the success of CropToCat
     return CropToCat(image).value_or(GenerateCuteCat());
   }

   // With or_else:
   Image GetCuteCat(const Image& image) {
     // GenerateCuteCat() only executes if CropToCat fails.
     return *CropToCat(image).or_else([](Status) { return GenerateCuteCat(); });
   }

``pw::Result<T>::transform``
----------------------------
The ``pw::Result<T>::transform`` member method will return a ``pw::Result<U>``
which contains the result of the invocation of the given function if ``*this``
contains a value. Otherwise, it returns a ``pw::Result<U>`` with the same
``pw::Status`` value as ``*this``.

The monadic methods for ``and_then`` and ``transform`` are fairly similar. The
primary difference is that ``and_then`` requires the provided function to return
a ``pw::Result``, whereas ``transform`` functions can return any type. Users
should be aware that if they provide a function that returns a ``pw::Result`` to
``transform``, this will return a ``pw::Result<pw::Result<U>>``.

.. code-block:: cpp

   // Expositional prototype of transform:
   template <typename T>
   class Result {
     template <typename U>
     Result<U> transform(Function<U(T)> func);
   };

   Result<int> ConvertStringToInteger(std::string_view);
   int MultiplyByTwo(int x);

   Result<int> x = ConvertStringToInteger("42")
                     .transform(MultiplyByTwo);

Results with custom error types: ``pw::expected``
=================================================
Most error codes can fit into one of the status codes supported by
``pw::Status``. However, custom error codes are occasionally needed for
interfacing with other libraries, or other special situations. This module
includes the ``pw::expected`` type for these situtaions.

``pw::expected`` is either an alias for ``std::expected`` or a polyfill for that
type if it is not available. This type has a similar use case to ``pw::Result``,
in that it either returns a type ``T`` or an error, but the error may be any
type ``E``, not just ``pw::Status``.  The ``PW_TRY`` and ``PW_TRY_ASSIGN``
macros do not work with ``pw::expected`` but it should be usable in any place
that ``std::expected`` from the ``C++23`` standard could be used.

.. code-block:: cpp

   #include "pw_result/expected.h"

   pw::expected<float, const char*> ReadBatteryVoltageOrError();

   void TrySensorRead() {
     pw::expected<float, const char*> voltage = ReadBatteryVoltageOrError();
     if (!voltage.has_value()) {
       PW_LOG_ERROR("Couldn't read battery: %s", voltage.error());
       return;
     }
     PW_LOG_ERROR("Battery: %f", voltage.value());
   }

For more information, see the `standard library reference
<https://en.cppreference.com/w/cpp/utility/expected>`_.

------
Design
------
.. inclusive-language: disable

``pw::Result<T>``'s implementation is closely based on Abseil's `StatusOr<T>
class <https://github.com/abseil/abseil-cpp/blob/master/absl/status/statusor.h>`_.
There are a few differences:

.. inclusive-language: enable

* ``pw::Result<T>`` objects represent their status code with a ``pw::Status``
  member rather than an ``absl::Status``. The ``pw::Status`` objects are less
  sophisticated but smaller than ``absl::Status`` objects. In particular,
  ``pw::Status`` objects do not support string errors, and are limited to the
  canonical error codes.
* ``pw::Result<T>`` objects are usable in ``constexpr`` statements if the value
  type ``T`` is trivially destructible.

-------
Roadmap
-------
This module is stable.

------------------
Code size analysis
------------------
The table below showcases the difference in size between functions returning a
``pw::Status`` with an output pointer, and functions returning a Result, in
various situations.

Note that these are simplified examples which do not necessarily reflect the
usage of ``pw::Result`` in real code. Make sure to always run your own size
reports to check if ``pw::Result`` is suitable for you.

.. include:: result_size
