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
85
86
87
88
89
90
91
92
93
94
95
96
|
module;
#include <asio.hpp>
#include <format>
#include <string_view>
export module ttwhy.routers:echo;
import ttwhy;
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_sequqnce = "\t"sv;
export template<typename StreamType>
struct echo
{
explicit echo(StreamType & stream)
: m_output_stream{stream}
{}
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.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(scanners::control_key key) -> asio::awaitable<void>
{
switch (key)
{
case scanners::control_key::backspace:
co_await asio::async_write(m_output_stream, asio::buffer(vte_backspace_sequence),
asio::as_tuple(asio::use_awaitable));
break;
case scanners::control_key::enter:
co_await asio::async_write(m_output_stream, asio::buffer(vte_newline_sequence),
asio::as_tuple(asio::use_awaitable));
break;
case scanners::control_key::tab:
co_await asio::async_write(m_output_stream, asio::buffer(vte_horizontal_tab_sequqnce),
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));
break;
};
}
auto process_navigation_key(scanners::navigation_key key) -> asio::awaitable<void>
{
switch (key)
{
case scanners::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
|