init: replace Result<> with expected<>

Android-base has an implementation of the future std::expected<>.
This provides the same baseline functionality as Result<>, so use it
instead of our own version.

Bug: 132145659
Test: boot, init unit tests
Change-Id: I11e61bcb5719b262a6420483ed51a762826a9e23
diff --git a/init/action.cpp b/init/action.cpp
index 94ccef2..a4f6936 100644
--- a/init/action.cpp
+++ b/init/action.cpp
@@ -127,7 +127,7 @@
     // report such failures unless we're running at the DEBUG log level.
     bool report_failure = !result.has_value();
     if (report_failure && android::base::GetMinimumLogSeverity() > android::base::DEBUG &&
-        result.error_errno() == ENOENT) {
+        result.error().as_errno == ENOENT) {
         report_failure = false;
     }
 
@@ -139,7 +139,7 @@
 
         LOG(INFO) << "Command '" << cmd_str << "' action=" << trigger_name << " (" << filename_
                   << ":" << command.line() << ") took " << duration.count() << "ms and "
-                  << (result ? "succeeded" : "failed: " + result.error_string());
+                  << (result ? "succeeded" : "failed: " + result.error().as_string);
     }
 }
 
diff --git a/init/keychords.cpp b/init/keychords.cpp
index f5ac44f..d0ca3e7 100644
--- a/init/keychords.cpp
+++ b/init/keychords.cpp
@@ -41,7 +41,7 @@
 
 Keychords::~Keychords() noexcept {
     if (inotify_fd_ >= 0) {
-        epoll_->UnregisterHandler(inotify_fd_).IgnoreError();
+        epoll_->UnregisterHandler(inotify_fd_);
         ::close(inotify_fd_);
     }
     while (!registration_.empty()) GeteventCloseDevice(registration_.begin()->first);
@@ -212,7 +212,7 @@
     auto it = registration_.find(device);
     if (it == registration_.end()) return;
     auto fd = (*it).second;
-    epoll_->UnregisterHandler(fd).IgnoreError();
+    epoll_->UnregisterHandler(fd);
     registration_.erase(it);
     ::close(fd);
 }
diff --git a/init/keychords_test.cpp b/init/keychords_test.cpp
index e5a6fd3..a3baeb1 100644
--- a/init/keychords_test.cpp
+++ b/init/keychords_test.cpp
@@ -213,7 +213,7 @@
 }
 
 void TestFrame::RelaxForMs(std::chrono::milliseconds wait) {
-    epoll_.Wait(wait).IgnoreError();
+    epoll_.Wait(wait);
 }
 
 void TestFrame::SetChord(int key, bool value) {
diff --git a/init/mount_handler.cpp b/init/mount_handler.cpp
index c8f0e76..b0b63c5 100644
--- a/init/mount_handler.cpp
+++ b/init/mount_handler.cpp
@@ -121,7 +121,7 @@
 }
 
 MountHandler::~MountHandler() {
-    if (fp_) epoll_->UnregisterHandler(fileno(fp_.get())).IgnoreError();
+    if (fp_) epoll_->UnregisterHandler(fileno(fp_.get()));
 }
 
 void MountHandler::MountHandlerFunction() {
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 0966b6c..54f68bb 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -527,13 +527,13 @@
 
             // start all animation classes if stopped.
             if (do_shutdown_animation) {
-                service->Start().IgnoreError();
+                service->Start();
             }
             service->SetShutdownCritical();  // will not check animation class separately
         }
 
         if (do_shutdown_animation) {
-            bootAnim->Start().IgnoreError();
+            bootAnim->Start();
             surfaceFlinger->SetShutdownCritical();
             bootAnim->SetShutdownCritical();
         }
diff --git a/init/result.h b/init/result.h
index 0e3fd3d..baa680d 100644
--- a/init/result.h
+++ b/init/result.h
@@ -68,14 +68,14 @@
 // if (!output) return Error() << "CalculateResult failed: " << output.error();
 // UseOutput(*output);
 
-#ifndef _INIT_RESULT_H
-#define _INIT_RESULT_H
+#pragma once
 
 #include <errno.h>
 
 #include <sstream>
 #include <string>
-#include <variant>
+
+#include <android-base/expected.h>
 
 namespace android {
 namespace init {
@@ -83,19 +83,24 @@
 struct ResultError {
     template <typename T>
     ResultError(T&& error_string, int error_errno)
-        : error_string(std::forward<T>(error_string)), error_errno(error_errno) {}
+        : as_string(std::forward<T>(error_string)), as_errno(error_errno) {}
 
-    std::string error_string;
-    int error_errno;
+    template <typename T>
+    operator android::base::expected<T, ResultError>() {
+        return android::base::unexpected(ResultError(as_string, as_errno));
+    }
+
+    std::string as_string;
+    int as_errno;
 };
 
 inline std::ostream& operator<<(std::ostream& os, const ResultError& t) {
-    os << t.error_string;
+    os << t.as_string;
     return os;
 }
 
 inline std::ostream& operator<<(std::ostream& os, ResultError&& t) {
-    os << std::move(t.error_string);
+    os << std::move(t.as_string);
     return os;
 }
 
@@ -105,20 +110,25 @@
     Error(int errno_to_append) : errno_(errno_to_append), append_errno_(true) {}
 
     template <typename T>
+    operator android::base::expected<T, ResultError>() {
+        return android::base::unexpected(ResultError(str(), errno_));
+    }
+
+    template <typename T>
     Error&& operator<<(T&& t) {
         ss_ << std::forward<T>(t);
         return std::move(*this);
     }
 
     Error&& operator<<(const ResultError& result_error) {
-        ss_ << result_error.error_string;
-        errno_ = result_error.error_errno;
+        ss_ << result_error.as_string;
+        errno_ = result_error.as_errno;
         return std::move(*this);
     }
 
     Error&& operator<<(ResultError&& result_error) {
-        ss_ << std::move(result_error.error_string);
-        errno_ = result_error.error_errno;
+        ss_ << std::move(result_error.as_string);
+        errno_ = result_error.as_errno;
         return std::move(*this);
     }
 
@@ -151,63 +161,10 @@
 }
 
 template <typename T>
-class [[nodiscard]] Result {
-  public:
-    Result() {}
-
-    template <typename U, typename... V,
-              typename = std::enable_if_t<!(std::is_same_v<std::decay_t<U>, Result<T>> &&
-                                            sizeof...(V) == 0)>>
-    Result(U&& result, V&&... results)
-        : contents_(std::in_place_index_t<0>(), std::forward<U>(result),
-                    std::forward<V>(results)...) {}
-
-    Result(Error&& error) : contents_(std::in_place_index_t<1>(), error.str(), error.get_errno()) {}
-    Result(const ResultError& result_error)
-        : contents_(std::in_place_index_t<1>(), result_error.error_string,
-                    result_error.error_errno) {}
-    Result(ResultError&& result_error)
-        : contents_(std::in_place_index_t<1>(), std::move(result_error.error_string),
-                    result_error.error_errno) {}
-
-    void IgnoreError() const {}
-
-    bool has_value() const { return contents_.index() == 0; }
-
-    T& value() & { return std::get<0>(contents_); }
-    const T& value() const & { return std::get<0>(contents_); }
-    T&& value() && { return std::get<0>(std::move(contents_)); }
-    const T&& value() const && { return std::get<0>(std::move(contents_)); }
-
-    const ResultError& error() const & { return std::get<1>(contents_); }
-    ResultError&& error() && { return std::get<1>(std::move(contents_)); }
-    const ResultError&& error() const && { return std::get<1>(std::move(contents_)); }
-
-    const std::string& error_string() const & { return std::get<1>(contents_).error_string; }
-    std::string&& error_string() && { return std::get<1>(std::move(contents_)).error_string; }
-    const std::string&& error_string() const && {
-        return std::get<1>(std::move(contents_)).error_string;
-    }
-
-    int error_errno() const { return std::get<1>(contents_).error_errno; }
-
-    explicit operator bool() const { return has_value(); }
-
-    T& operator*() & { return value(); }
-    const T& operator*() const & { return value(); }
-    T&& operator*() && { return std::move(value()); }
-    const T&& operator*() const && { return std::move(value()); }
-
-    T* operator->() { return &value(); }
-    const T* operator->() const { return &value(); }
-
-  private:
-    std::variant<T, ResultError> contents_;
-};
+using Result = android::base::expected<T, ResultError>;
 
 using Success = std::monostate;
 
 }  // namespace init
 }  // namespace android
 
-#endif
diff --git a/init/result_test.cpp b/init/result_test.cpp
index 327b444..d3d04a0 100644
--- a/init/result_test.cpp
+++ b/init/result_test.cpp
@@ -74,8 +74,8 @@
     ASSERT_FALSE(result);
     ASSERT_FALSE(result.has_value());
 
-    EXPECT_EQ(0, result.error_errno());
-    EXPECT_EQ("failure1", result.error_string());
+    EXPECT_EQ(0, result.error().as_errno);
+    EXPECT_EQ("failure1", result.error().as_string);
 }
 
 TEST(result, result_error_empty) {
@@ -83,8 +83,8 @@
     ASSERT_FALSE(result);
     ASSERT_FALSE(result.has_value());
 
-    EXPECT_EQ(0, result.error_errno());
-    EXPECT_EQ("", result.error_string());
+    EXPECT_EQ(0, result.error().as_errno);
+    EXPECT_EQ("", result.error().as_string);
 }
 
 TEST(result, result_error_rvalue) {
@@ -98,8 +98,8 @@
     ASSERT_FALSE(MakeRvalueErrorResult());
     ASSERT_FALSE(MakeRvalueErrorResult().has_value());
 
-    EXPECT_EQ(0, MakeRvalueErrorResult().error_errno());
-    EXPECT_EQ("failure1", MakeRvalueErrorResult().error_string());
+    EXPECT_EQ(0, MakeRvalueErrorResult().error().as_errno);
+    EXPECT_EQ("failure1", MakeRvalueErrorResult().error().as_string);
 }
 
 TEST(result, result_errno_error) {
@@ -110,8 +110,8 @@
     ASSERT_FALSE(result);
     ASSERT_FALSE(result.has_value());
 
-    EXPECT_EQ(test_errno, result.error_errno());
-    EXPECT_EQ("failure1: "s + strerror(test_errno), result.error_string());
+    EXPECT_EQ(test_errno, result.error().as_errno);
+    EXPECT_EQ("failure1: "s + strerror(test_errno), result.error().as_string);
 }
 
 TEST(result, result_errno_error_no_text) {
@@ -122,8 +122,8 @@
     ASSERT_FALSE(result);
     ASSERT_FALSE(result.has_value());
 
-    EXPECT_EQ(test_errno, result.error_errno());
-    EXPECT_EQ(strerror(test_errno), result.error_string());
+    EXPECT_EQ(test_errno, result.error().as_errno);
+    EXPECT_EQ(strerror(test_errno), result.error().as_string);
 }
 
 TEST(result, result_error_from_other_result) {
@@ -138,8 +138,8 @@
     ASSERT_FALSE(result2);
     ASSERT_FALSE(result2.has_value());
 
-    EXPECT_EQ(0, result.error_errno());
-    EXPECT_EQ(error_text, result.error_string());
+    EXPECT_EQ(0, result.error().as_errno);
+    EXPECT_EQ(error_text, result.error().as_string);
 }
 
 TEST(result, result_error_through_ostream) {
@@ -154,8 +154,8 @@
     ASSERT_FALSE(result2);
     ASSERT_FALSE(result2.has_value());
 
-    EXPECT_EQ(0, result.error_errno());
-    EXPECT_EQ(error_text, result.error_string());
+    EXPECT_EQ(0, result.error().as_errno);
+    EXPECT_EQ(error_text, result.error().as_string);
 }
 
 TEST(result, result_errno_error_through_ostream) {
@@ -174,12 +174,12 @@
     ASSERT_FALSE(result2);
     ASSERT_FALSE(result2.has_value());
 
-    EXPECT_EQ(test_errno, result.error_errno());
-    EXPECT_EQ(error_text + ": " + strerror(test_errno), result.error_string());
+    EXPECT_EQ(test_errno, result.error().as_errno);
+    EXPECT_EQ(error_text + ": " + strerror(test_errno), result.error().as_string);
 }
 
 TEST(result, constructor_forwarding) {
-    auto result = Result<std::string>(5, 'a');
+    auto result = Result<std::string>(std::in_place, 5, 'a');
 
     ASSERT_TRUE(result);
     ASSERT_TRUE(result.has_value());
@@ -298,8 +298,8 @@
     auto result = return_result_result_with_error();
     ASSERT_TRUE(result);
     ASSERT_FALSE(*result);
-    EXPECT_EQ("failure string", result->error_string());
-    EXPECT_EQ(6, result->error_errno());
+    EXPECT_EQ("failure string", (*result).error().as_string);
+    EXPECT_EQ(6, (*result).error().as_errno);
 }
 
 // This test requires that we disable the forwarding reference constructor if Result<T> is the
@@ -312,7 +312,9 @@
         int value_;
     };
 
-    auto return_test_struct = []() -> Result<TestStruct> { return {Result<TestStruct>(6), 6}; };
+    auto return_test_struct = []() -> Result<TestStruct> {
+        return Result<TestStruct>(std::in_place, Result<TestStruct>(std::in_place, 6), 6);
+    };
 
     auto result = return_test_struct();
     ASSERT_TRUE(result);
@@ -326,7 +328,7 @@
 
 TEST(result, die_on_get_error_succesful_result) {
     Result<std::string> result = "success";
-    ASSERT_DEATH(result.error_string(), "");
+    ASSERT_DEATH(result.error(), "");
 }
 
 }  // namespace init
diff --git a/init/rlimit_parser.cpp b/init/rlimit_parser.cpp
index 1e0754a..476a46a 100644
--- a/init/rlimit_parser.cpp
+++ b/init/rlimit_parser.cpp
@@ -77,7 +77,7 @@
         return Error() << "Could not parse hard limit '" << args[3] << "'";
     }
 
-    return {resource, limit};
+    return std::pair{resource, limit};
 }
 
 }  // namespace init
diff --git a/init/rlimit_parser_test.cpp b/init/rlimit_parser_test.cpp
index 659ba8a..e690bf6 100644
--- a/init/rlimit_parser_test.cpp
+++ b/init/rlimit_parser_test.cpp
@@ -43,8 +43,8 @@
     auto result = ParseRlimit(input);
 
     ASSERT_FALSE(result) << "input: " << input[1];
-    EXPECT_EQ(expected_result, result.error_string());
-    EXPECT_EQ(0, result.error_errno());
+    EXPECT_EQ(expected_result, result.error().as_string);
+    EXPECT_EQ(0, result.error().as_errno);
 }
 
 TEST(rlimit, RlimitSuccess) {
diff --git a/init/service.cpp b/init/service.cpp
index ccc37b7..6887d7b 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -1383,7 +1383,7 @@
             continue;
         }
         if (auto result = service->Start(); !result) {
-            LOG(ERROR) << result.error_string();
+            LOG(ERROR) << result.error().as_string;
         }
     }
     delayed_service_names_.clear();
diff --git a/init/subcontext.cpp b/init/subcontext.cpp
index 092c51c..467b0d2 100644
--- a/init/subcontext.cpp
+++ b/init/subcontext.cpp
@@ -141,8 +141,8 @@
         reply->set_success(true);
     } else {
         auto* failure = reply->mutable_failure();
-        failure->set_error_string(result.error_string());
-        failure->set_error_errno(result.error_errno());
+        failure->set_error_string(result.error().as_string);
+        failure->set_error_errno(result.error().as_errno);
     }
 }
 
@@ -177,7 +177,7 @@
 
         auto init_message = ReadMessage(init_fd_);
         if (!init_message) {
-            if (init_message.error_errno() == 0) {
+            if (init_message.error().as_errno == 0) {
                 // If the init file descriptor was closed, let's exit quietly. If
                 // this was accidental, init will restart us. If init died, this
                 // avoids calling abort(3) unnecessarily.
diff --git a/init/subcontext_benchmark.cpp b/init/subcontext_benchmark.cpp
index eae03e3..6307993 100644
--- a/init/subcontext_benchmark.cpp
+++ b/init/subcontext_benchmark.cpp
@@ -39,7 +39,7 @@
     free(context);
 
     while (state.KeepRunning()) {
-        subcontext.Execute(std::vector<std::string>{"return_success"}).IgnoreError();
+        subcontext.Execute(std::vector<std::string>{"return_success"});
     }
 
     if (subcontext.pid() > 0) {
diff --git a/init/subcontext_test.cpp b/init/subcontext_test.cpp
index 230203a..c0662a4 100644
--- a/init/subcontext_test.cpp
+++ b/init/subcontext_test.cpp
@@ -69,7 +69,7 @@
         auto result = subcontext.Execute(std::vector<std::string>{"return_pids_as_error"});
         ASSERT_FALSE(result);
 
-        auto pids = Split(result.error_string(), " ");
+        auto pids = Split(result.error().as_string, " ");
         ASSERT_EQ(2U, pids.size());
         auto our_pid = std::to_string(getpid());
         EXPECT_NE(our_pid, pids[0]);
@@ -116,7 +116,7 @@
 
         auto result = subcontext.Execute(std::vector<std::string>{"return_words_as_error"});
         ASSERT_FALSE(result);
-        EXPECT_EQ(Join(expected_words, " "), result.error_string());
+        EXPECT_EQ(Join(expected_words, " "), result.error().as_string);
         EXPECT_EQ(first_pid, subcontext.pid());
     });
 }
@@ -130,7 +130,7 @@
 
         auto result2 = subcontext.Execute(std::vector<std::string>{"generate_sane_error"});
         ASSERT_FALSE(result2);
-        EXPECT_EQ("Sane error!", result2.error_string());
+        EXPECT_EQ("Sane error!", result2.error().as_string);
         EXPECT_NE(subcontext.pid(), first_pid);
     });
 }
@@ -139,7 +139,7 @@
     RunTest([](auto& subcontext, auto& context_string) {
         auto result = subcontext.Execute(std::vector<std::string>{"return_context_as_error"});
         ASSERT_FALSE(result);
-        ASSERT_EQ(context_string, result.error_string());
+        ASSERT_EQ(context_string, result.error().as_string);
     });
 }
 
@@ -167,7 +167,7 @@
         };
         auto result = subcontext.ExpandArgs(args);
         ASSERT_FALSE(result);
-        EXPECT_EQ("Failed to expand '" + args[1] + "'", result.error_string());
+        EXPECT_EQ("Failed to expand '" + args[1] + "'", result.error().as_string);
     });
 }
 
diff --git a/init/util_test.cpp b/init/util_test.cpp
index 1b5afba..8bf672c 100644
--- a/init/util_test.cpp
+++ b/init/util_test.cpp
@@ -34,7 +34,7 @@
     auto file_contents = ReadFile("/proc/does-not-exist");
     EXPECT_EQ(ENOENT, errno);
     ASSERT_FALSE(file_contents);
-    EXPECT_EQ("open() failed: No such file or directory", file_contents.error_string());
+    EXPECT_EQ("open() failed: No such file or directory", file_contents.error().as_string);
 }
 
 TEST(util, ReadFileGroupWriteable) {
@@ -45,7 +45,7 @@
     EXPECT_NE(-1, fchmodat(AT_FDCWD, tf.path, 0620, AT_SYMLINK_NOFOLLOW)) << strerror(errno);
     auto file_contents = ReadFile(tf.path);
     ASSERT_FALSE(file_contents) << strerror(errno);
-    EXPECT_EQ("Skipping insecure file", file_contents.error_string());
+    EXPECT_EQ("Skipping insecure file", file_contents.error().as_string);
 }
 
 TEST(util, ReadFileWorldWiteable) {
@@ -56,7 +56,7 @@
     EXPECT_NE(-1, fchmodat(AT_FDCWD, tf.path, 0602, AT_SYMLINK_NOFOLLOW)) << strerror(errno);
     auto file_contents = ReadFile(tf.path);
     ASSERT_FALSE(file_contents) << strerror(errno);
-    EXPECT_EQ("Skipping insecure file", file_contents.error_string());
+    EXPECT_EQ("Skipping insecure file", file_contents.error().as_string);
 }
 
 TEST(util, ReadFileSymbolicLink) {
@@ -65,7 +65,8 @@
     auto file_contents = ReadFile("/charger");
     EXPECT_EQ(ELOOP, errno);
     ASSERT_FALSE(file_contents);
-    EXPECT_EQ("open() failed: Too many symbolic links encountered", file_contents.error_string());
+    EXPECT_EQ("open() failed: Too many symbolic links encountered",
+              file_contents.error().as_string);
 }
 
 TEST(util, ReadFileSuccess) {
@@ -130,7 +131,7 @@
 
     decoded_uid = DecodeUid("toot");
     EXPECT_FALSE(decoded_uid);
-    EXPECT_EQ("getpwnam failed: No such file or directory", decoded_uid.error_string());
+    EXPECT_EQ("getpwnam failed: No such file or directory", decoded_uid.error().as_string);
 
     decoded_uid = DecodeUid("123");
     EXPECT_TRUE(decoded_uid);