| // Copyright 2021 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_DEVELOPER_DEBUG_SHARED_STATUS_H_ |
| #define SRC_DEVELOPER_DEBUG_SHARED_STATUS_H_ |
| |
| #include <optional> |
| #include <string> |
| |
| #if defined(__Fuchsia__) |
| #include <zircon/status.h> |
| #endif |
| |
| namespace debug { |
| |
| class Status; |
| |
| #if defined(__Fuchsia__) |
| |
| // If there is an error and no message is given, the ZX_* constant will be queried and used. |
| // If given, the message will be used for most display purposes instead of the platform value, so |
| // if the value is important and you use a custom message, it should be manually included. |
| // |
| // These are split rather than using default values to avoid creating empty std::strings in the |
| // common case. |
| Status ZxStatus(zx_status_t s); |
| Status ZxStatus(zx_status_t s, std::string msg); |
| |
| #else |
| |
| // As with the ZxStatus version above, this will automatically use the strerror() strinf if no |
| // message is given. |
| Status ErrnoStatus(int en); |
| Status ErrnoStatus(int en, std::string msg); |
| |
| #endif |
| |
| // A cross-platform status value. It has three modes: |
| // |
| // - OK. This is generated by the default constructor and indicates "no error". |
| // |
| // - Platform error: This is generated by one of the above platform-specific helpers. It has a |
| // platform error value (zx_status_t or errno), and it also looks up the corresponding string |
| // from the operating system |
| // |
| // - Cross-platform error: A nonempty error message is passed to the debug::Status() constructor |
| // containing the error message. There is no platform_error number. |
| class Status { |
| public: |
| // No error. For error construction, use one of the helpers above. |
| Status() = default; |
| |
| // Constructor for a platform-independent error. The string must not be empty or it will assert. |
| explicit Status(std::string msg); |
| |
| // Code creating error should use the platform-specific helpers above. This is for code that |
| // needs to create from some known internal values. The tag structure is to discourage direct use |
| // of this function except when you really need it. |
| struct InternalValues {}; |
| Status(InternalValues tag, std::optional<int64_t> pe, std::string msg) |
| : platform_error_(pe), message_(std::move(msg)) {} |
| |
| bool ok() const { return !platform_error_ && message_.empty(); } |
| bool has_error() const { return !ok(); } |
| |
| // These assume the error is set. |
| const std::optional<int64_t>& platform_error() const { return platform_error_; } |
| const std::string& message() const { return message_; } |
| |
| bool operator==(const Status& other) const { |
| return platform_error_ == other.platform_error_ && message_ == other.message_; |
| } |
| bool operator!=(const Status& other) const { return !operator==(other); } |
| |
| private: |
| std::optional<int64_t> platform_error_; |
| std::string message_; |
| }; |
| |
| } // namespace debug |
| |
| #endif // SRC_DEVELOPER_DEBUG_SHARED_STATUS_H_ |