diff options
Diffstat (limited to 'ttwhy/io.cppm')
| -rw-r--r-- | ttwhy/io.cppm | 84 |
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 |
