blob: f79a19304ff00cc4a8776ef42d2ec3fb09fb03a2 [file]
// 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_