aboutsummaryrefslogtreecommitdiff
path: root/ttwhy/routers/echo.cppm
blob: 41b7b516ad813f0db025728a71e89f23d1be0b87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
module;

#include <asio.hpp>

#include <format>
#include <string_view>

export module ttwhy.routers:echo;

import ttwhy;

namespace ttwhy::routers
{

  using namespace std::string_view_literals;

  constexpr auto vte_backspace_sequence = "\b \b"sv;

  export template<typename StreamType>
  struct echo
  {
    explicit echo(StreamType & stream)
        : m_output_stream{stream}
    {}

    auto process(ttwhy::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<character_event, event_type>)
            {
              co_await process_character(event.value);
            }
            else if constexpr (std::same_as<control_event, event_type>)
            {
              co_await process_control_key(event.key);
            }
            else if constexpr (std::same_as<navigation_event, event_type>)
            {
              co_await process_navigation_key(event.key);
            }
          },
          event);
    }

  private:
    auto process_character(char character) -> asio::awaitable<void>
    {
      co_await asio::async_write(m_output_stream, asio::buffer(&character, 1), asio::as_tuple(asio::use_awaitable));
    }

    auto process_control_key(control_key key) -> asio::awaitable<void>
    {
      switch (key)
      {
        case control_key::backspace:
          co_await asio::async_write(m_output_stream, asio::buffer(vte_backspace_sequence),
                                     asio::as_tuple(asio::use_awaitable));
          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));
      };
    }

    auto process_navigation_key(navigation_key key) -> asio::awaitable<void>
    {
      switch (key)
      {
        case navigation_key::delete_key:
          co_await asio::async_write(m_output_stream, asio::buffer("{DEL}"), asio::as_tuple(asio::use_awaitable));
          break;
        default:
          co_await asio::async_write(m_output_stream, asio::buffer(std::format("{{NAV:{}}}", std::to_underlying(key))),
                                     asio::as_tuple(asio::use_awaitable));
      }
    }

    StreamType & m_output_stream;
  };

}  // namespace ttwhy::routers