aboutsummaryrefslogtreecommitdiff
path: root/ttwhy/routers/echo.cppm
diff options
context:
space:
mode:
Diffstat (limited to 'ttwhy/routers/echo.cppm')
-rw-r--r--ttwhy/routers/echo.cppm206
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