#include "write_irc.hpp" #include "connection.hpp" #include #include namespace { auto write_irc(Connection& connection, std::string message) -> void { connection.write_line(std::move(message)); } auto is_invalid_last(char x) -> bool { return x == '\0' || x == '\r' || x == '\n'; } auto is_invalid(char x) -> bool { return x == '\0' || x == '\r' || x == '\n' || x == ' '; } auto write_irc(Connection& connection, std::string front, std::string_view last) -> void { if (last.end() != std::find_if(last.begin(), last.end(), is_invalid_last)) { throw std::runtime_error{"bad irc argument"}; } front += " :"; front += last; write_irc(connection, std::move(front)); } template auto write_irc(Connection& connection, std::string front, std::string_view next, Args ...rest) -> void { if (next.empty() || next.front() == ':' || next.end() != std::find_if(next.begin(), next.end(), is_invalid)) { throw std::runtime_error{"bad irc argument"}; } front += " "; front += next; write_irc(connection, std::move(front), rest...); } } // namespace auto send_ping(Connection& connection, std::string_view txt) -> void { write_irc(connection, "PING", txt); } auto send_pong(Connection& connection, std::string_view txt) -> void { write_irc(connection, "PONG", txt); } auto send_pass(Connection& connection, std::string_view password) -> void { write_irc(connection, "PASS", password); } auto send_user(Connection& connection, std::string_view user, std::string_view real) -> void { write_irc(connection, "USER", user, "*", "*", real); } auto send_nick(Connection& connection, std::string_view nick) -> void { write_irc(connection, "NICK", nick); } auto send_cap_ls(Connection& connection) -> void { write_irc(connection, "CAP", "LS", "302"); } auto send_cap_end(Connection& connection) -> void { write_irc(connection, "CAP", "END"); } auto send_cap_req(Connection& connection, std::string_view caps) -> void { write_irc(connection, "CAP", "REQ", caps); } auto send_privmsg(Connection& connection, std::string_view target, std::string_view message) -> void { write_irc(connection, "PRIVMSG", target, message); } auto send_notice(Connection& connection, std::string_view target, std::string_view message) -> void { write_irc(connection, "NOTICE", target, message); }