[zbitl] Use std::optional instead of fitx::result for storage_error

fitx::result is not meant for storing values.

Change-Id: Id723d7add8eea3d54b04f8ad7de558e3a133a2e0
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/412743
Commit-Queue: Roland McGrath <mcgrathr@google.com>
Reviewed-by: Corey Tabaka <eieio@google.com>
Reviewed-by: Joshua Seaton <joshuaseaton@google.com>
Testability-Review: Corey Tabaka <eieio@google.com>
diff --git a/zircon/kernel/lib/userabi/userboot/zbi.cc b/zircon/kernel/lib/userabi/userboot/zbi.cc
index ca2b664..910563e 100644
--- a/zircon/kernel/lib/userabi/userboot/zbi.cc
+++ b/zircon/kernel/lib/userabi/userboot/zbi.cc
@@ -93,13 +93,12 @@
 
   if (auto check = zbi.take_error(); check.is_error()) {
     auto error = check.error_value();
-    if (error.storage_error.is_ok()) {
+    if (error.storage_error) {
       fail(log, "invalid ZBI: %.*s at offset %#x\n", static_cast<int>(error.zbi_error.size()),
            error.zbi_error.data(), error.item_offset);
     } else {
       fail(log, "invalid ZBI: %.*s at offset %#x: %s\n", static_cast<int>(error.zbi_error.size()),
-           error.zbi_error.data(), error.item_offset,
-           zx_status_get_string(error.storage_error.error_value()));
+           error.zbi_error.data(), error.item_offset, zx_status_get_string(*error.storage_error));
     }
   } else {
     fail(log, "no '/boot' bootfs in bootstrap message\n");
diff --git a/zircon/kernel/tests/zbitl_tests.cc b/zircon/kernel/tests/zbitl_tests.cc
index 43b69b0..1dd375b 100644
--- a/zircon/kernel/tests/zbitl_tests.cc
+++ b/zircon/kernel/tests/zbitl_tests.cc
@@ -80,7 +80,7 @@
   auto error = zbi.take_error();
   ASSERT_TRUE(error.is_error());
   // The error should not be storage-related.
-  EXPECT_TRUE(error.error_value().storage_error.is_ok());
+  EXPECT_FALSE(error.error_value().storage_error);
 
   END_TEST;
 }
diff --git a/zircon/system/ulib/zbitl/include/lib/zbitl/view.h b/zircon/system/ulib/zbitl/include/lib/zbitl/view.h
index 78d28df..e474b76 100644
--- a/zircon/system/ulib/zbitl/include/lib/zbitl/view.h
+++ b/zircon/system/ulib/zbitl/include/lib/zbitl/view.h
@@ -10,6 +10,7 @@
 #include <zircon/boot/image.h>
 
 #include <functional>
+#include <optional>
 #include <type_traits>
 #include <variant>
 
@@ -190,9 +191,9 @@
     uint32_t item_offset = 0;
 
     /// This reflects the underlying error from accessing the Storage object,
-    /// if any.  If storage_error.is_error() is false, then the error is in the
-    /// format of the contents of the ZBI, not in accessing the contents.
-    fitx::result<typename Traits::error_type> storage_error{};
+    /// if any.  If storage_error.has_value() is false, then the error is in
+    /// the format of the contents of the ZBI, not in accessing the contents.
+    std::optional<typename Traits::error_type> storage_error{};
   };
 
   /// Check the container for errors after using iterators.  When begin() or
@@ -252,7 +253,7 @@
         *this = view_->end();
       } else if (auto header = Traits::Header(view_->storage(), offset_); header.is_error()) {
         // Failed to read the next header.
-        Fail("cannot read item header", fitx::error{std::move(header.error_value())});
+        Fail("cannot read item header", std::move(header.error_value()));
       } else if (auto header_error = CheckHeader<Check>(header.value(), view_->limit_ - offset_);
                  header_error.is_error()) {
         Fail(header_error.error_value());
@@ -261,14 +262,14 @@
         offset_ += static_cast<uint32_t>(sizeof(zbi_header_t));
         if (auto payload = Traits::Payload(view_->storage(), offset_, header_->length);
             payload.is_error()) {
-          Fail("cannot extract payload view", fitx::error{std::move(payload.error_value())});
+          Fail("cannot extract payload view", std::move(payload.error_value()));
         } else {
           offset_ += ZBI_ALIGN(header_->length);
           payload_ = std::move(payload.value());
           if constexpr (Check == Checking::kCrc) {
             if (auto crc = Traits::Crc32(view_->storage(), offset_, header_->length);
                 crc.is_error()) {
-              Fail("cannot compute payload CRC32", fitx::error{std::move(crc.error_value())});
+              Fail("cannot compute payload CRC32", std::move(crc.error_value()));
             }
           }
         }
@@ -358,7 +359,7 @@
     }
 
     void Fail(std::string_view sv,
-              fitx::result<typename Traits::error_type> storage_error = fitx::ok()) {
+              std::optional<typename Traits::error_type> storage_error = std::nullopt) {
       view_->Fail({sv, offset_, std::move(storage_error)});
       *this = view_->end();
     }
@@ -374,40 +375,40 @@
   fitx::result<Error, zbi_header_t> container_header() {
     auto capacity_error = Traits::Capacity(storage());
     if (capacity_error.is_error()) {
-      return fitx::error(Error{"cannot determine storage capacity", 0,
-                               fitx::error{std::move(capacity_error.error_value())}});
+      return fitx::error{
+          Error{"cannot determine storage capacity", 0, std::move(capacity_error.error_value())}};
     }
     uint32_t capacity = capacity_error.value();
 
     // Minimal bounds check before trying to read.
     if (capacity < sizeof(zbi_header_t)) {
       return fitx::error(
-          Error{"storage capacity too small for ZBI container header", capacity, fitx::ok()});
+          Error{"storage capacity too small for ZBI container header", capacity, {}});
     }
 
     // Read and validate the container header.
     auto header_error = Traits::Header(storage(), 0);
     if (header_error.is_error()) {
       // Failed to read the container header.
-      return fitx::error(Error{"cannot read container header", 0,
-                               fitx::error{std::move(header_error.error_value())}});
+      return fitx::error{
+          Error{"cannot read container header", 0, std::move(header_error.error_value())}};
     }
 
     const header_type header(std::move(header_error.value()));
 
     auto check_error = CheckHeader<Check>(*header, capacity);
     if (check_error.is_error()) {
-      return fitx::error(Error{check_error.error_value(), 0, fitx::ok()});
+      return fitx::error(Error{check_error.error_value(), 0, {}});
     }
 
     if constexpr (Check != Checking::kPermissive) {
       if (header->flags & ZBI_FLAG_CRC32) {
-        return fitx::error(Error{"container header has CRC32 flag", 0, fitx::ok()});
+        return fitx::error(Error{"container header has CRC32 flag", 0, {}});
       }
     }
 
     if (header->length % ZBI_ALIGNMENT != 0) {
-      return fitx::error(Error{"container header has misaligned length", 0, fitx::ok()});
+      return fitx::error(Error{"container header has misaligned length", 0, {}});
     }
 
     return fitx::ok(*header);
diff --git a/zircon/system/ulib/zbitl/test/tests.h b/zircon/system/ulib/zbitl/test/tests.h
index fa64765..c4ffb74 100644
--- a/zircon/system/ulib/zbitl/test/tests.h
+++ b/zircon/system/ulib/zbitl/test/tests.h
@@ -55,9 +55,9 @@
   ASSERT_TRUE(error.is_error(), "no error when header cannot be read??");
   EXPECT_FALSE(error.error_value().zbi_error.empty(), "empty zbi_error string!!");
   if (expect_storage_error) {
-    EXPECT_TRUE(error.error_value().storage_error.is_error());
+    EXPECT_TRUE(error.error_value().storage_error.has_value());
   } else {
-    EXPECT_TRUE(error.error_value().storage_error.is_ok());
+    EXPECT_FALSE(error.error_value().storage_error.has_value());
   }
 }
 
@@ -136,7 +136,7 @@
   auto error = view.take_error();
   ASSERT_TRUE(error.is_error());
   // The error shouldn't be one of storage.
-  EXPECT_TRUE(error.error_value().storage_error.is_ok());
+  EXPECT_FALSE(error.error_value().storage_error);
 }
 
 template <typename StorageIo>