blob: e608ed5cd22331ca57106b16956938974d090d92 [file] [log] [blame]
James Kuszmaul847927d2024-05-23 15:33:18 -07001#include "aos/util/status.h"
2
Austin Schuh99f7c6a2024-06-25 22:07:44 -07003#include "absl/log/log.h"
4
5#include "aos/containers/inlined_vector.h"
6
James Kuszmaul847927d2024-05-23 15:33:18 -07007namespace aos {
James Kuszmaul053d42a2024-05-30 16:46:08 -07008namespace {
9// Constructs a string view from the provided buffer if it has data and
10// otherwise uses the provided string view. Used in copy/move constructors to
11// figure out whether we should use the buffer or keep the pointer to the
12// existing std::string_view (as is the case for when we store a pointer to a
13// string literal).
14static std::string_view MakeStringViewFromBufferOrView(
15 const aos::InlinedVector<char, Error::kStaticMessageLength> &buffer,
16 const std::string_view &view) {
17 return (buffer.size() > 0) ? std::string_view(buffer.begin(), buffer.end())
18 : view;
19}
20} // namespace
21Error::Error(StatusCode code, std::string_view message,
22 std::optional<std::source_location> source_location)
James Kuszmaul847927d2024-05-23 15:33:18 -070023 : code_(code),
24 owned_message_(message.begin(), message.end()),
25 message_(owned_message_.data(), owned_message_.size()),
26 source_location_(std::move(source_location)) {}
James Kuszmaul053d42a2024-05-30 16:46:08 -070027Error::Error(StatusCode code, const char *message,
28 std::optional<std::source_location> source_location)
James Kuszmaul847927d2024-05-23 15:33:18 -070029 : code_(code),
30 message_(message),
31 source_location_(std::move(source_location)) {}
32
James Kuszmaul053d42a2024-05-30 16:46:08 -070033Error::Error(Error &&other)
James Kuszmaul847927d2024-05-23 15:33:18 -070034 : code_(other.code_),
35 owned_message_(std::move(other.owned_message_)),
36 message_(MakeStringViewFromBufferOrView(owned_message_, other.message_)),
37 source_location_(std::move(other.source_location_)) {
38 // Because the internal string view contains a pointer to the owned_message_
39 // buffer, we need to have a manually written move constructor to manage it.
40 other.message_ = {};
41}
James Kuszmaul053d42a2024-05-30 16:46:08 -070042Error &Error::operator=(Error &&other) {
James Kuszmaul847927d2024-05-23 15:33:18 -070043 std::swap(*this, other);
44 return *this;
45}
James Kuszmaul053d42a2024-05-30 16:46:08 -070046Error::Error(const Error &other)
James Kuszmaul847927d2024-05-23 15:33:18 -070047 : code_(other.code_),
48 owned_message_(other.owned_message_),
49 message_(MakeStringViewFromBufferOrView(owned_message_, other.message_)),
50 source_location_(other.source_location_) {}
51
James Kuszmaul053d42a2024-05-30 16:46:08 -070052std::string Error::ToString() const {
James Kuszmaul847927d2024-05-23 15:33:18 -070053 std::string source_info = "";
54 if (source_location_.has_value()) {
55 source_info = absl::StrFormat(
56 "%s:%d in %s: ", source_location_->file_name(),
57 source_location_->line(), source_location_->function_name());
58 }
59
James Kuszmaul053d42a2024-05-30 16:46:08 -070060 return absl::StrFormat("%sErrored with code of %d and message: %s",
61 source_info, code(), message());
James Kuszmaul847927d2024-05-23 15:33:18 -070062}
63
64template <>
James Kuszmaul053d42a2024-05-30 16:46:08 -070065void CheckExpected<void>(const Result<void> &expected) {
James Kuszmaul847927d2024-05-23 15:33:18 -070066 if (expected.has_value()) {
67 return;
68 }
69 LOG(FATAL) << expected.error().ToString();
70}
James Kuszmaul053d42a2024-05-30 16:46:08 -070071
72int ResultExitCode(const Result<void> &expected) {
73 return expected.has_value() ? static_cast<int>(Error::StatusCode::kOk)
74 : expected.error().code();
75}
James Kuszmaul847927d2024-05-23 15:33:18 -070076} // namespace aos