#pragma once #include #include #include #include namespace cvmmap_streamer { using error_t = int; enum class ErrorCode : error_t { Ok = 0, InvalidArgument, InvalidConfig, Unsupported, NotReady, BackendUnavailable, AllocationFailed, Io, Network, Protocol, Encoder, ExternalLibrary, Serialization, ChildProcess, EndOfStream, Internal, }; inline constexpr ErrorCode ERR_OK = ErrorCode::Ok; inline constexpr ErrorCode ERR_INVALID_ARGUMENT = ErrorCode::InvalidArgument; inline constexpr ErrorCode ERR_INVALID_CONFIG = ErrorCode::InvalidConfig; inline constexpr ErrorCode ERR_UNSUPPORTED = ErrorCode::Unsupported; inline constexpr ErrorCode ERR_NOT_READY = ErrorCode::NotReady; inline constexpr ErrorCode ERR_BACKEND_UNAVAILABLE = ErrorCode::BackendUnavailable; inline constexpr ErrorCode ERR_ALLOCATION_FAILED = ErrorCode::AllocationFailed; inline constexpr ErrorCode ERR_IO = ErrorCode::Io; inline constexpr ErrorCode ERR_NETWORK = ErrorCode::Network; inline constexpr ErrorCode ERR_PROTOCOL = ErrorCode::Protocol; inline constexpr ErrorCode ERR_ENCODER = ErrorCode::Encoder; inline constexpr ErrorCode ERR_EXTERNAL_LIBRARY = ErrorCode::ExternalLibrary; inline constexpr ErrorCode ERR_SERIALIZATION = ErrorCode::Serialization; inline constexpr ErrorCode ERR_CHILD_PROCESS = ErrorCode::ChildProcess; inline constexpr ErrorCode ERR_END_OF_STREAM = ErrorCode::EndOfStream; inline constexpr ErrorCode ERR_INTERNAL = ErrorCode::Internal; struct Error { ErrorCode code{ERR_OK}; std::string detail{}; }; template using Result = std::expected; using Status = Result; [[nodiscard]] inline std::unexpected unexpected_error(ErrorCode code, std::string detail = {}) { return std::unexpected(Error{ .code = code, .detail = std::move(detail), }); } [[nodiscard]] inline std::string_view error_code_name(ErrorCode code) { switch (code) { case ERR_OK: return "ok"; case ERR_INVALID_ARGUMENT: return "invalid_argument"; case ERR_INVALID_CONFIG: return "invalid_config"; case ERR_UNSUPPORTED: return "unsupported"; case ERR_NOT_READY: return "not_ready"; case ERR_BACKEND_UNAVAILABLE: return "backend_unavailable"; case ERR_ALLOCATION_FAILED: return "allocation_failed"; case ERR_IO: return "io"; case ERR_NETWORK: return "network"; case ERR_PROTOCOL: return "protocol"; case ERR_ENCODER: return "encoder"; case ERR_EXTERNAL_LIBRARY: return "external_library"; case ERR_SERIALIZATION: return "serialization"; case ERR_CHILD_PROCESS: return "child_process"; case ERR_END_OF_STREAM: return "end_of_stream"; case ERR_INTERNAL: return "internal"; default: return "unknown"; } } [[nodiscard]] inline std::string format_error(const Error &error) { if (error.detail.empty()) { return std::string(error_code_name(error.code)); } return std::string(error_code_name(error.code)) + ": " + error.detail; } }