aboutsummaryrefslogtreecommitdiff
path: root/ttwhy/io.cppm
diff options
context:
space:
mode:
Diffstat (limited to 'ttwhy/io.cppm')
-rw-r--r--ttwhy/io.cppm84
1 files changed, 84 insertions, 0 deletions
diff --git a/ttwhy/io.cppm b/ttwhy/io.cppm
new file mode 100644
index 0000000..cbd3902
--- /dev/null
+++ b/ttwhy/io.cppm
@@ -0,0 +1,84 @@
+module;
+
+#include <asio.hpp>
+
+#include <expected>
+#include <format>
+#include <string>
+
+export module ttwhy:io;
+
+namespace ttwhy::io
+{
+
+ export template<typename Stream>
+ auto handle_signals(Stream & stream) -> asio::awaitable<std::error_code>
+ {
+ auto executor = co_await asio::this_coro::executor;
+ auto signals = asio::signal_set{executor, SIGINT, SIGTERM};
+
+ auto [error, signal] = co_await signals.async_wait(asio::as_tuple(asio::use_awaitable));
+ if (!error)
+ {
+ auto message = std::format("Received signal {}, exiting ...\n", signal);
+ co_await asio::async_write(stream, asio::buffer(message), asio::use_awaitable);
+ }
+ co_return error;
+ }
+
+ export template<typename InputStream, typename ErrorStream>
+ auto read(InputStream & input_stream, ErrorStream & error_stream)
+ -> asio::awaitable<std::expected<std::string, asio::error_code>>
+ {
+ auto data = std::string{15, '\0'};
+
+ auto [error, read] = co_await input_stream.async_read_some(asio::buffer(data), asio::as_tuple(asio::use_awaitable));
+
+ if (error)
+ {
+ auto message = std::format("{}, exiting ...\n", error.message());
+ co_await asio::async_write(error_stream, asio::buffer(message), asio::use_awaitable);
+ co_return std::unexpected{error};
+ }
+
+ data.resize(read);
+ co_return data;
+ }
+
+ export template<typename OutputStream, typename ErrorStream>
+ auto write(std::string const & string, OutputStream & output_stream, ErrorStream & error_stream)
+ -> asio::awaitable<asio::error_code>
+ {
+ auto [error, written] =
+ co_await asio::async_write(output_stream, asio::buffer(string), asio::as_tuple(asio::use_awaitable));
+
+ if (error)
+ {
+ auto message = std::format("{}, exiting ...\n", error.message());
+ co_await asio::async_write(error_stream, asio::buffer(message), asio::use_awaitable);
+ }
+
+ co_return error;
+ }
+
+ export template<typename InputStream, typename OutputStream, typename ErrorStream>
+ auto echo(InputStream & input_stream, OutputStream & output_stream, ErrorStream & error_stream)
+ -> asio::awaitable<asio::error_code>
+ {
+ while (true)
+ {
+ auto input = co_await read(input_stream, error_stream);
+ if (!input.has_value())
+ {
+ co_return input.error();
+ }
+
+ auto write_error = co_await write(input.value(), output_stream, error_stream);
+ if (write_error)
+ {
+ co_return write_error;
+ }
+ }
+ }
+
+} // namespace ttwhy::io