diff options
Diffstat (limited to 'ttwhy/routers/echo.cppm')
| -rw-r--r-- | ttwhy/routers/echo.cppm | 206 |
1 files changed, 0 insertions, 206 deletions
diff --git a/ttwhy/routers/echo.cppm b/ttwhy/routers/echo.cppm deleted file mode 100644 index c9cd7c7..0000000 --- a/ttwhy/routers/echo.cppm +++ /dev/null @@ -1,206 +0,0 @@ -module; - -#include <asio.hpp> - -#include <algorithm> - -#include <cstddef> -#include <format> -#include <string_view> - -export module ttwhy.routers:echo; - -import ttwhy.scanners; - -namespace ttwhy::routers -{ - - using namespace std::string_view_literals; - - constexpr auto vte_backspace_sequence = "\b \b"sv; - constexpr auto vte_newline_sequence = "\r\n"sv; - constexpr auto vte_horizontal_tab_sequence = "\t"sv; - constexpr auto vte_cursor_left_sequence = "\x1b[D"sv; - constexpr auto vte_cursor_right_sequence = "\x1b[C"sv; - constexpr auto vte_delete_character_sequence = "\x1b[P"sv; - constexpr auto vte_cursor_left_sequence_format = "\x1b[{}D"sv; - constexpr auto vte_cursor_right_sequence_format = "\x1b[{}C"sv; - - export template<typename StreamType> - struct echo - { - explicit echo(StreamType & stream) - : m_output_stream{stream} - {} - - [[nodiscard]] auto cursor_position() const noexcept -> std::size_t - { - return m_cursor_position; - } - - [[nodiscard]] auto max_position() const noexcept -> std::size_t - { - return m_max_position; - } - - auto process(scanners::input_event event) -> asio::awaitable<void> - { - co_await std::visit( - [&](auto && event) -> asio::awaitable<void> { - using event_type = std::decay_t<decltype(event)>; - - if constexpr (std::same_as<scanners::character_event, event_type>) - { - co_await process_character(event.value); - } - else if constexpr (std::same_as<scanners::control_event, event_type>) - { - co_await process_control_key(event.key); - } - else if constexpr (std::same_as<scanners::navigation_event, event_type>) - { - co_await process_navigation_key(event); - } - }, - event); - } - - private: - auto process_character(char character) -> asio::awaitable<void> - { - auto [error, bytes_written] = - co_await asio::async_write(m_output_stream, asio::buffer(&character, 1), asio::as_tuple(asio::use_awaitable)); - if (!error) - { - m_cursor_position += bytes_written; - m_max_position = std::max(m_max_position, m_cursor_position); - } - } - - auto process_control_key(scanners::control_key key) -> asio::awaitable<void> - { - switch (key) - { - case scanners::control_key::backspace: - if (m_cursor_position > 0) - { - auto [error, bytes_written] = co_await asio::async_write( - m_output_stream, asio::buffer(vte_backspace_sequence), asio::as_tuple(asio::use_awaitable)); - if (!error) - { - if (m_cursor_position == m_max_position) - { - --m_max_position; - } - --m_cursor_position; - } - } - break; - case scanners::control_key::enter: - { - auto [error, bytes_written] = co_await asio::async_write(m_output_stream, asio::buffer(vte_newline_sequence), - asio::as_tuple(asio::use_awaitable)); - if (!error) - { - m_cursor_position = 0; - m_max_position = 0; - } - break; - } - case scanners::control_key::tab: - { - auto [error, bytes_written] = co_await asio::async_write( - m_output_stream, asio::buffer(vte_horizontal_tab_sequence), asio::as_tuple(asio::use_awaitable)); - if (!error) - { - auto const tab_stop = 8uz - (m_cursor_position % 8uz); - m_cursor_position += tab_stop; - m_max_position = std::max(m_max_position, m_cursor_position); - } - break; - } - default: - co_await asio::async_write(m_output_stream, asio::buffer(std::format("{{CTRL:{}}}", std::to_underlying(key))), - asio::as_tuple(asio::use_awaitable)); - break; - }; - } - - auto process_navigation_key(scanners::navigation_event event) -> asio::awaitable<void> - { - switch (event.key) - { - case scanners::navigation_key::left: - if (m_cursor_position > 0) - { - auto [error, bytes_written] = co_await asio::async_write( - m_output_stream, asio::buffer(vte_cursor_left_sequence), asio::as_tuple(asio::use_awaitable)); - if (!error) - { - --m_cursor_position; - } - } - break; - - case scanners::navigation_key::right: - if (m_cursor_position < m_max_position) - { - auto [error, bytes_written] = co_await asio::async_write( - m_output_stream, asio::buffer(vte_cursor_right_sequence), asio::as_tuple(asio::use_awaitable)); - if (!error) - { - ++m_cursor_position; - } - } - break; - - case scanners::navigation_key::home: - if (m_cursor_position > 0) - { - auto sequence = std::format(vte_cursor_left_sequence_format, m_cursor_position); - auto [error, bytes_written] = co_await asio::async_write(m_output_stream, asio::buffer(sequence), - asio::as_tuple(asio::use_awaitable)); - if (!error) - { - m_cursor_position = 0; - } - } - break; - - case scanners::navigation_key::end: - if (m_cursor_position < m_max_position) - { - auto const distance = m_max_position - m_cursor_position; - auto sequence = std::format(vte_cursor_right_sequence_format, distance); - auto [error, bytes_written] = co_await asio::async_write(m_output_stream, asio::buffer(sequence), - asio::as_tuple(asio::use_awaitable)); - if (!error) - { - m_cursor_position = m_max_position; - } - } - break; - - case scanners::navigation_key::delete_key: - if (m_cursor_position < m_max_position) - { - auto [error, bytes_written] = co_await asio::async_write( - m_output_stream, asio::buffer(vte_delete_character_sequence), asio::as_tuple(asio::use_awaitable)); - if (!error) - { - --m_max_position; - } - } - break; - - default: - break; - } - } - - StreamType & m_output_stream; - std::size_t m_cursor_position{}; - std::size_t m_max_position{}; - }; - -} // namespace ttwhy::routers |
