/* * Copyright (c) 2021, Kyle Pereira * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include namespace IMAP { enum class CommandType { Noop, }; enum class ResponseType : unsigned { }; class Parser; struct Command { public: CommandType type; int tag; Vector args; }; enum class ResponseStatus { Bad, No, OK, }; class ResponseData { public: [[nodiscard]] unsigned response_type() const { return m_response_type; } ResponseData() : m_response_type(0) { } ResponseData(ResponseData&) = delete; ResponseData(ResponseData&&) = default; ResponseData& operator=(const ResponseData&) = delete; ResponseData& operator=(ResponseData&&) = default; [[nodiscard]] bool contains_response_type(ResponseType response_type) const { return (static_cast(response_type) & m_response_type) != 0; } void add_response_type(ResponseType response_type) { m_response_type = m_response_type | static_cast(response_type); } private: unsigned m_response_type; }; class SolidResponse { // Parser is allowed to set up fields friend class Parser; public: ResponseStatus status() { return m_status; } int tag() const { return m_tag; } ResponseData& data() { return m_data; } String response_text() { return m_response_text; }; SolidResponse() : SolidResponse(ResponseStatus::Bad, -1) { } SolidResponse(ResponseStatus status, int tag) : m_status(status) , m_tag(tag) , m_data(ResponseData()) { } private: ResponseStatus m_status; String m_response_text; unsigned m_tag; ResponseData m_data; }; struct ContinueRequest { String data; }; template class Promise : public Core::Object { C_OBJECT(Promise); private: Optional m_pending; public: Function on_resolved; void resolve(Result&& result) { m_pending = move(result); if (on_resolved) on_resolved(m_pending.value()); } bool is_resolved() { return m_pending.has_value(); }; Result await() { while (!is_resolved()) { Core::EventLoop::current().pump(); } return m_pending.release_value(); } // Converts a Promise to a Promise using a function func: A -> B template RefPtr> map(Function func) { RefPtr> new_promise = Promise::construct(); on_resolved = [new_promise, func](Result& result) mutable { auto t = func(result); new_promise->resolve(move(t)); }; return new_promise; } }; using Response = Variant; } // An RFC 2822 message // https://datatracker.ietf.org/doc/html/rfc2822 struct Message { String data; };