/* * Copyright (c) 2021, Kyle Pereira * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include namespace IMAP { class Client { friend class Parser; public: Client(StringView host, unsigned port, bool start_with_tls); Optional>> connect(); RefPtr>> send_command(Command&&); RefPtr>> send_simple_command(CommandType); void send_raw(StringView data); RefPtr>> login(StringView username, StringView password); RefPtr>> list(StringView reference_name, StringView mailbox_name); RefPtr>> lsub(StringView reference_name, StringView mailbox_name); RefPtr>> select(StringView string); RefPtr>> examine(StringView string); RefPtr>> search(Optional charset, Vector&& search_keys, bool uid); RefPtr>> fetch(FetchCommand request, bool uid); RefPtr>> store(StoreMethod, Sequence, bool silent, Vector const& flags, bool uid); RefPtr>> copy(Sequence sequence_set, StringView name, bool uid); RefPtr>> create_mailbox(StringView name); RefPtr>> delete_mailbox(StringView name); RefPtr>> subscribe(StringView mailbox); RefPtr>> unsubscribe(StringView mailbox); RefPtr>> rename(StringView from, StringView to); RefPtr>> authenticate(StringView method); RefPtr>> idle(); RefPtr>> finish_idle(); RefPtr>> status(StringView mailbox, Vector const& types); RefPtr>> append(StringView mailbox, Message&& message, Optional> flags = {}, Optional date_time = {}); void close(); Function unrequested_response_callback; private: StringView m_host; unsigned m_port; RefPtr m_socket; RefPtr m_tls_socket; void on_ready_to_receive(); void on_tls_ready_to_receive(); bool m_tls; int m_current_command = 1; bool connect_tls(); bool connect_plaintext(); // Sent but response not received Vector>>> m_pending_promises; // Not yet sent Vector m_command_queue {}; RefPtr> m_connect_pending {}; ByteBuffer m_buffer; Parser m_parser; bool m_expecting_response { false }; void handle_parsed_response(ParseStatus&& parse_status); void send_next_command(); }; }