Add Status object to AOS
This provides a type, comparable to absl::Status or std::error_code,
that can be used for communicating error messages back to users.
Future revisions may introduce additional sophistication, with either
more elaborate error codes or with more ability to communicate
structured information at run-time. However, doing those things in ways
that play nice with realtime code will require some additional effort,
so for now we keep the API relatively simple.
Change-Id: I9b9fa89bfd37bb18dbac7672939a867dac81600a
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/util/status.cc b/aos/util/status.cc
new file mode 100644
index 0000000..de372db
--- /dev/null
+++ b/aos/util/status.cc
@@ -0,0 +1,55 @@
+#include "aos/util/status.h"
+
+namespace aos {
+Status::Status(StatusCode code, std::string_view message,
+ std::optional<std::source_location> source_location)
+ : code_(code),
+ owned_message_(message.begin(), message.end()),
+ message_(owned_message_.data(), owned_message_.size()),
+ source_location_(std::move(source_location)) {}
+Status::Status(StatusCode code, const char *message,
+ std::optional<std::source_location> source_location)
+ : code_(code),
+ message_(message),
+ source_location_(std::move(source_location)) {}
+
+Status::Status(Status &&other)
+ : code_(other.code_),
+ owned_message_(std::move(other.owned_message_)),
+ message_(MakeStringViewFromBufferOrView(owned_message_, other.message_)),
+ source_location_(std::move(other.source_location_)) {
+ // Because the internal string view contains a pointer to the owned_message_
+ // buffer, we need to have a manually written move constructor to manage it.
+ other.message_ = {};
+}
+Status &Status::operator=(Status &&other) {
+ std::swap(*this, other);
+ return *this;
+}
+Status::Status(const Status &other)
+ : code_(other.code_),
+ owned_message_(other.owned_message_),
+ message_(MakeStringViewFromBufferOrView(owned_message_, other.message_)),
+ source_location_(other.source_location_) {}
+
+std::string Status::ToString() const {
+ std::string source_info = "";
+ if (source_location_.has_value()) {
+ source_info = absl::StrFormat(
+ "%s:%d in %s: ", source_location_->file_name(),
+ source_location_->line(), source_location_->function_name());
+ }
+
+ return absl::StrFormat("%sStatus is %s with code of %d and message: %s",
+ source_info, ok() ? "okay" : "errored", code(),
+ message());
+}
+
+template <>
+void CheckExpected<void>(const tl::expected<void, Status> &expected) {
+ if (expected.has_value()) {
+ return;
+ }
+ LOG(FATAL) << expected.error().ToString();
+}
+} // namespace aos