From 20817642d96095e83e1d4b8517f4ffbb32847fd2 Mon Sep 17 00:00:00 2001 From: Marcelo Zimbres Date: Sun, 8 Aug 2021 14:53:07 +0200 Subject: [PATCH] Refactoring: - Moves read and write header to detail. - Adds namespace detail to all files in detail directory. --- README.md | 6 +- examples/async_basic.cpp | 8 +- include/aedis/aedis.hpp | 2 - include/aedis/{detail => }/commands.hpp | 0 include/aedis/connection.hpp | 8 +- include/aedis/detail/impl/parser.ipp | 4 +- include/aedis/{ => detail}/impl/read.ipp | 5 +- .../aedis/detail/impl/response_buffers.ipp | 4 +- include/aedis/detail/parser.hpp | 5 +- include/aedis/{ => detail}/read.hpp | 43 ++- include/aedis/detail/response_base.hpp | 4 +- include/aedis/detail/response_buffers.hpp | 6 +- include/aedis/detail/response_types.hpp | 26 +- include/aedis/detail/responses.hpp | 11 +- include/aedis/{ => detail}/write.hpp | 29 +- include/aedis/{detail => }/impl/commands.ipp | 2 +- include/aedis/impl/connection.ipp | 6 +- include/aedis/impl/src.hpp | 4 +- include/aedis/impl/types.ipp | 5 +- include/aedis/{config.hpp => net.hpp} | 0 include/aedis/receiver_base.hpp | 19 +- include/aedis/request.hpp | 5 +- include/aedis/resp_types.hpp | 13 +- include/aedis/types.hpp | 3 +- include/aedis/version.hpp | 1 - tests/general.cpp | 339 +++++++++--------- 26 files changed, 277 insertions(+), 281 deletions(-) rename include/aedis/{detail => }/commands.hpp (100%) rename include/aedis/{ => detail}/impl/read.ipp (87%) rename include/aedis/{ => detail}/read.hpp (92%) rename include/aedis/{ => detail}/write.hpp (86%) rename include/aedis/{detail => }/impl/commands.ipp (98%) rename include/aedis/{config.hpp => net.hpp} (100%) diff --git a/README.md b/README.md index b939f227..4d971111 100644 --- a/README.md +++ b/README.md @@ -26,13 +26,13 @@ below public: receiver(std::shared_ptr conn) : conn_{conn} { } - void on_hello(resp::array_type& v) noexcept override + void on_hello(array_type& v) noexcept override { conn_->send(f); } - void on_ping(resp::simple_string_type& s) noexcept override + void on_ping(simple_string_type& s) noexcept override { std::cout << "PING: " << s << std::endl; } - void on_quit(resp::simple_string_type& s) noexcept override + void on_quit(simple_string_type& s) noexcept override { std::cout << "QUIT: " << s << std::endl; } }; ``` diff --git a/examples/async_basic.cpp b/examples/async_basic.cpp index da716799..f0fc917a 100644 --- a/examples/async_basic.cpp +++ b/examples/async_basic.cpp @@ -24,16 +24,16 @@ private: public: myreceiver(std::shared_ptr conn) : conn_{conn} { } - void on_hello(resp::array_type& v) noexcept override + void on_hello(array_type& v) noexcept override { conn_->send(f); } - void on_ping(resp::simple_string_type& s) noexcept override + void on_ping(simple_string_type& s) noexcept override { std::cout << "PING: " << s << std::endl; } - void on_quit(resp::simple_string_type& s) noexcept override + void on_quit(simple_string_type& s) noexcept override { std::cout << "QUIT: " << s << std::endl; } - void on_push(resp::array_type& s) noexcept override + void on_push(array_type& s) noexcept override { std::cout << "on_push: "; print(s); } }; diff --git a/include/aedis/aedis.hpp b/include/aedis/aedis.hpp index 98c62e58..a1054edc 100644 --- a/include/aedis/aedis.hpp +++ b/include/aedis/aedis.hpp @@ -7,9 +7,7 @@ #pragma once -#include #include #include -#include #include #include diff --git a/include/aedis/detail/commands.hpp b/include/aedis/commands.hpp similarity index 100% rename from include/aedis/detail/commands.hpp rename to include/aedis/commands.hpp diff --git a/include/aedis/connection.hpp b/include/aedis/connection.hpp index 9a2c0af6..c86525fc 100644 --- a/include/aedis/connection.hpp +++ b/include/aedis/connection.hpp @@ -10,12 +10,12 @@ #include #include +#include #include -#include "config.hpp" +#include "net.hpp" #include "types.hpp" #include "request.hpp" -#include "read.hpp" namespace aedis { @@ -37,8 +37,8 @@ private: net::steady_timer timer_; net::ip::tcp::socket socket_; std::string buffer_; - resp::response_buffers resps_; - request_queue reqs_; + detail::response_buffers resps_; + detail::request_queue reqs_; bool reconnect_ = false; config conf_; diff --git a/include/aedis/detail/impl/parser.ipp b/include/aedis/detail/impl/parser.ipp index 666d4639..a907ce89 100644 --- a/include/aedis/detail/impl/parser.ipp +++ b/include/aedis/detail/impl/parser.ipp @@ -7,7 +7,7 @@ #include -namespace aedis { namespace resp { +namespace aedis { namespace detail { // Converts a decimal number in ascii format to an integer. long long length(char const* p) @@ -140,5 +140,5 @@ std::size_t parser::advance(char const* data, std::size_t n) return n; } -} // resp +} // detail } // aedis diff --git a/include/aedis/impl/read.ipp b/include/aedis/detail/impl/read.ipp similarity index 87% rename from include/aedis/impl/read.ipp rename to include/aedis/detail/impl/read.ipp index 0fd9c64b..f14b1c35 100644 --- a/include/aedis/impl/read.ipp +++ b/include/aedis/detail/impl/read.ipp @@ -5,9 +5,9 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -#include +#include -namespace aedis { +namespace aedis { namespace detail { bool queue_pop(request_queue& reqs) { @@ -23,4 +23,5 @@ bool queue_pop(request_queue& reqs) return false; } +} // detail } // aedis diff --git a/include/aedis/detail/impl/response_buffers.ipp b/include/aedis/detail/impl/response_buffers.ipp index 3b7781c4..c5056a59 100644 --- a/include/aedis/detail/impl/response_buffers.ipp +++ b/include/aedis/detail/impl/response_buffers.ipp @@ -9,7 +9,7 @@ #include -namespace aedis { namespace resp { +namespace aedis { namespace detail { void response_buffers::forward_transaction( std::deque> const& ids, @@ -200,6 +200,6 @@ response_base* response_buffers::select(commands cmd, types t) } } -} // resp +} // detail } // aedis diff --git a/include/aedis/detail/parser.hpp b/include/aedis/detail/parser.hpp index a1b1a0e9..7a2be6cf 100644 --- a/include/aedis/detail/parser.hpp +++ b/include/aedis/detail/parser.hpp @@ -11,8 +11,9 @@ #include "response_base.hpp" -namespace aedis { namespace resp { +namespace aedis { namespace detail { +// resp3 parser. class parser { public: enum class bulk_type @@ -60,5 +61,5 @@ public: auto bulk_length() const noexcept { return bulk_length_; } }; -} // resp +} // detail } // aedis diff --git a/include/aedis/read.hpp b/include/aedis/detail/read.hpp similarity index 92% rename from include/aedis/read.hpp rename to include/aedis/detail/read.hpp index 6ddb76b7..e86bd240 100644 --- a/include/aedis/read.hpp +++ b/include/aedis/detail/read.hpp @@ -21,15 +21,15 @@ #include #include -#include -#include -#include +#include +#include +#include -#include "config.hpp" -#include "types.hpp" -#include "request.hpp" +#include "parser.hpp" +#include "response_buffers.hpp" +#include "response_base.hpp" -namespace aedis { namespace resp { +namespace aedis { namespace detail { // The parser supports up to 5 levels of nested structures. The first // element in the sizes stack is a sentinel and must be different from @@ -43,7 +43,7 @@ private: int start_ = 1; public: - parse_op(AsyncReadStream& stream, Storage* buf, resp::response_base* res) + parse_op(AsyncReadStream& stream, Storage* buf, response_base* res) : stream_ {stream} , buf_ {buf} , parser_ {res} @@ -108,7 +108,7 @@ template auto read( SyncReadStream& stream, Storage& buf, - resp::response_base& res, + response_base& res, boost::system::error_code& ec) { parser p {&res}; @@ -143,7 +143,7 @@ std::size_t read( SyncReadStream& stream, Storage& buf, - resp::response_base& res) + response_base& res) { boost::system::error_code ec; auto const n = read(stream, buf, res, ec); @@ -163,7 +163,7 @@ template < auto async_read( AsyncReadStream& stream, Storage& buffer, - resp::response_base& res, + response_base& res, CompletionToken&& token = net::default_completion_token_t{}) { @@ -235,8 +235,6 @@ auto async_read_type( stream); } -} // resp - struct queue_elem { request req; bool sent = false; @@ -262,10 +260,10 @@ async_reader( boost::system::error_code& ec) { // Used to queue the cmds of a transaction. - std::deque> trans; + std::deque> trans; for (;;) { - auto t = resp::types::invalid; + auto t = types::invalid; co_await async_read_type( socket, buffer, @@ -275,10 +273,10 @@ async_reader( if (ec) co_return; - assert(t != resp::types::invalid); + assert(t != types::invalid); auto cmd = commands::unknown; - if (t != resp::types::push) { + if (t != types::push) { assert(!std::empty(reqs)); assert(!std::empty(reqs.front().req.cmds)); cmd = reqs.front().req.cmds.front(); @@ -289,7 +287,7 @@ async_reader( auto const trans_empty = std::empty(trans); if (is_multi || (!trans_empty && !is_exec)) { - resp::response_static_string<6> tmp; + response_static_string<6> tmp; co_await async_read( socket, buffer, @@ -308,7 +306,7 @@ async_reader( // Pushes the command in the transction command queue that will be // processed when exec arrives. - trans.push_back({reqs.front().req.cmds.front(), resp::types::invalid}); + trans.push_back({reqs.front().req.cmds.front(), types::invalid}); reqs.front().req.cmds.pop(); continue; } @@ -344,7 +342,7 @@ async_reader( reqs.front().sent = true; co_await async_write( socket, - reqs.front().req, + net::buffer(reqs.front().req.payload), net::redirect_error(net::use_awaitable, ec)); if (ec) { @@ -374,7 +372,7 @@ async_reader( resps.forward(cmd, t, recv); - if (t == resp::types::push) + if (t == types::push) continue; if (!queue_pop(reqs)) @@ -386,7 +384,7 @@ async_reader( reqs.front().sent = true; co_await async_write( socket, - reqs.front().req, + net::buffer(reqs.front().req.payload), net::redirect_error(net::use_awaitable, ec)); if (ec) { @@ -402,4 +400,5 @@ async_reader( } } +} // detail } // aedis diff --git a/include/aedis/detail/response_base.hpp b/include/aedis/detail/response_base.hpp index 9c615e92..2b40ba0b 100644 --- a/include/aedis/detail/response_base.hpp +++ b/include/aedis/detail/response_base.hpp @@ -12,7 +12,7 @@ #include -namespace aedis { namespace resp { +namespace aedis { namespace detail { struct response_base { virtual void pop() {} @@ -35,6 +35,6 @@ struct response_base { virtual ~response_base() {} }; -} // resp +} // detail } // aedis diff --git a/include/aedis/detail/response_buffers.hpp b/include/aedis/detail/response_buffers.hpp index 879e4c7d..91ef1598 100644 --- a/include/aedis/detail/response_buffers.hpp +++ b/include/aedis/detail/response_buffers.hpp @@ -9,11 +9,11 @@ #include #include +#include -#include "commands.hpp" #include "response_types.hpp" -namespace aedis { namespace resp { +namespace aedis { namespace detail { #define EXPAND_RECEIVER_CASE(var, x) case commands::x: recv.on_##x(var.result); break @@ -50,6 +50,6 @@ public: void forward(commands cmd, types t, receiver_base& recv); }; -} // resp +} // detail } // aedis diff --git a/include/aedis/detail/response_types.hpp b/include/aedis/detail/response_types.hpp index b0d552fb..41e91d58 100644 --- a/include/aedis/detail/response_types.hpp +++ b/include/aedis/detail/response_types.hpp @@ -7,22 +7,22 @@ #pragma once -#include "responses.hpp" +#include -namespace aedis { namespace resp { +namespace aedis { namespace detail { -using response_array = response_basic_array; -using response_map = response_basic_map; -using response_set = response_basic_set; +using response_array = detail::response_basic_array; +using response_map = detail::response_basic_map; +using response_set = detail::response_basic_set; -using response_blob_string = response_basic_blob_string; -using response_blob_error = response_basic_blob_error; -using response_simple_string = response_basic_simple_string; -using response_simple_error = response_basic_simple_error; -using response_big_number = response_basic_big_number; -using response_verbatim_string = response_basic_verbatim_string; -using response_streamed_string_part = response_basic_streamed_string_part; +using response_blob_string = detail::response_basic_blob_string; +using response_blob_error = detail::response_basic_blob_error; +using response_simple_string = detail::response_basic_simple_string; +using response_simple_error = detail::response_basic_simple_error; +using response_big_number = detail::response_basic_big_number; +using response_verbatim_string = detail::response_basic_verbatim_string; +using response_streamed_string_part = detail::response_basic_streamed_string_part; -} // resp +} // detail } // aedis diff --git a/include/aedis/detail/responses.hpp b/include/aedis/detail/responses.hpp index 10e73a61..a781cf06 100644 --- a/include/aedis/detail/responses.hpp +++ b/include/aedis/detail/responses.hpp @@ -17,16 +17,18 @@ #include #include -#include -#include +#include #include #include +#include +#include +#include #include "response_base.hpp" #include -namespace aedis { namespace resp { +namespace aedis { namespace detail { template typename std::enable_if::value, void>::type @@ -368,6 +370,5 @@ struct response_basic_static_map : response_base { std::array result; }; -} // resp +} // detail } // aedis - diff --git a/include/aedis/write.hpp b/include/aedis/detail/write.hpp similarity index 86% rename from include/aedis/write.hpp rename to include/aedis/detail/write.hpp index 62f0b50e..ead0f92b 100644 --- a/include/aedis/write.hpp +++ b/include/aedis/detail/write.hpp @@ -9,12 +9,14 @@ #include -#include "config.hpp" -#include "request.hpp" +#include +#include + +#include "read.hpp" #include -namespace aedis { +namespace aedis { namespace detail { template std::size_t @@ -46,24 +48,6 @@ std::size_t write( return bytes_transferred; } -template< - class AsyncWriteStream, - class CompletionToken = - net::default_completion_token_t> -auto -async_write( - AsyncWriteStream& stream, - request& req, - CompletionToken&& token = - net::default_completion_token_t{}) -{ - static_assert(boost::beast::is_async_write_stream< - AsyncWriteStream>::value, - "AsyncWriteStream type requirements not met"); - - return net::async_write(stream, net::buffer(req.payload), token); -} - template struct writer_op { AsyncReadStream& stream; @@ -157,5 +141,6 @@ bool queue_writer( return empty; } -} // aedis +} // detail +} // aedis diff --git a/include/aedis/detail/impl/commands.ipp b/include/aedis/impl/commands.ipp similarity index 98% rename from include/aedis/detail/impl/commands.ipp rename to include/aedis/impl/commands.ipp index e33e36ec..4a9812f5 100644 --- a/include/aedis/detail/impl/commands.ipp +++ b/include/aedis/impl/commands.ipp @@ -5,7 +5,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -#include +#include #include diff --git a/include/aedis/impl/connection.ipp b/include/aedis/impl/connection.ipp index 8d4ca359..3c8a5926 100644 --- a/include/aedis/impl/connection.ipp +++ b/include/aedis/impl/connection.ipp @@ -6,7 +6,7 @@ */ #include -#include +#include namespace aedis { @@ -51,12 +51,12 @@ net::awaitable connection::worker_coro(receiver_base& recv) continue; } - async_writer(socket_, reqs_, timer_, net::detached); + detail::async_writer(socket_, reqs_, timer_, net::detached); ec = {}; co_await co_spawn( ex, - async_reader(socket_, buffer_, resps_, recv, reqs_, ec), + detail::async_reader(socket_, buffer_, resps_, recv, reqs_, ec), net::use_awaitable); if (ec) { diff --git a/include/aedis/impl/src.hpp b/include/aedis/impl/src.hpp index e441ab76..fd1c72df 100644 --- a/include/aedis/impl/src.hpp +++ b/include/aedis/impl/src.hpp @@ -6,9 +6,9 @@ */ #include -#include #include +#include +#include #include -#include #include diff --git a/include/aedis/impl/types.ipp b/include/aedis/impl/types.ipp index e43babe2..36e3c0ef 100644 --- a/include/aedis/impl/types.ipp +++ b/include/aedis/impl/types.ipp @@ -9,7 +9,7 @@ #include -namespace aedis { namespace resp { +namespace aedis { #define EXPAND_TYPE_CASE(x) case types::x: return #x @@ -60,10 +60,9 @@ types to_type(char c) } } -} // resp } // aedis -std::ostream& operator<<(std::ostream& os, aedis::resp::types type) +std::ostream& operator<<(std::ostream& os, aedis::types type) { os << to_string(type); return os; diff --git a/include/aedis/config.hpp b/include/aedis/net.hpp similarity index 100% rename from include/aedis/config.hpp rename to include/aedis/net.hpp diff --git a/include/aedis/receiver_base.hpp b/include/aedis/receiver_base.hpp index c6c5c08f..5678dcc1 100644 --- a/include/aedis/receiver_base.hpp +++ b/include/aedis/receiver_base.hpp @@ -12,11 +12,12 @@ #include "types.hpp" #include "request.hpp" +#include "resp_types.hpp" namespace aedis { -#define RECEIVER_FUNCTION_REF(name, cmd) virtual void on_##cmd(resp::name& v) noexcept { } -#define RECEIVER_FUNCTION(name, cmd) virtual void on_##cmd(resp::name v) noexcept { } +#define RECEIVER_FUNCTION_REF(name, cmd) virtual void on_##cmd(name& v) noexcept { } +#define RECEIVER_FUNCTION(name, cmd) virtual void on_##cmd(name v) noexcept { } /** Receiver base class. * @@ -28,14 +29,6 @@ namespace aedis { * https://github.com/antirez/RESP3/blob/74adea588783e463c7e84793b325b088fe6edd1c/spec.md#resp3-types */ -struct transaction_element { - int depth; - resp::types type; - int expected_size = -1; - commands command = commands::unknown; - std::vector value; -}; - class receiver_base { public: @@ -171,13 +164,13 @@ public: RECEIVER_FUNCTION_REF(blob_string_type, hget); /// Callback for push notifications - virtual void on_push(resp::array_type& v) noexcept { } + virtual void on_push(array_type& v) noexcept { } /// Callback for simple error. - virtual void on_simple_error(commands cmd, resp::simple_error_type& v) noexcept { } + virtual void on_simple_error(commands cmd, simple_error_type& v) noexcept { } /// Callback for blob error. - virtual void on_blob_error(commands cmd, resp::blob_error_type& v) noexcept { } + virtual void on_blob_error(commands cmd, blob_error_type& v) noexcept { } /// Callback from null responses. virtual void on_null(commands cmd) noexcept { } diff --git a/include/aedis/request.hpp b/include/aedis/request.hpp index 6d1bb175..1108a120 100644 --- a/include/aedis/request.hpp +++ b/include/aedis/request.hpp @@ -16,9 +16,8 @@ #include #include -#include - -#include "config.hpp" +#include "commands.hpp" +#include "net.hpp" namespace aedis { namespace resp { diff --git a/include/aedis/resp_types.hpp b/include/aedis/resp_types.hpp index a0f0a29a..62f11393 100644 --- a/include/aedis/resp_types.hpp +++ b/include/aedis/resp_types.hpp @@ -10,7 +10,9 @@ #include #include -namespace aedis { namespace resp { +#include "commands.hpp" + +namespace aedis { template > using basic_array_type = std::vector; @@ -81,5 +83,12 @@ using big_number_type = basic_big_number; using verbatim_string_type = basic_verbatim_string; using streamed_string_part_type = basic_streamed_string_part; -} // resp +struct transaction_element { + int depth; + types type; + int expected_size = -1; + commands command = commands::unknown; + std::vector value; +}; + } // aedis diff --git a/include/aedis/types.hpp b/include/aedis/types.hpp index a3eb401c..dc4e4c92 100644 --- a/include/aedis/types.hpp +++ b/include/aedis/types.hpp @@ -9,7 +9,7 @@ #include -namespace aedis { namespace resp { +namespace aedis { enum class types { array @@ -34,5 +34,4 @@ enum class types types to_type(char c); std::ostream& operator<<(std::ostream& os, types t); -} // resp } // aedis diff --git a/include/aedis/version.hpp b/include/aedis/version.hpp index e2cc8645..c2d9d075 100644 --- a/include/aedis/version.hpp +++ b/include/aedis/version.hpp @@ -1,4 +1,3 @@ - /* Copyright (c) 2019 - 2021 Marcelo Zimbres Silva (mzimbres at gmail dot com) * * This Source Code Form is subject to the terms of the Mozilla Public diff --git a/tests/general.cpp b/tests/general.cpp index 999ddef7..889c270b 100644 --- a/tests/general.cpp +++ b/tests/general.cpp @@ -40,7 +40,7 @@ private: public: test_receiver(std::shared_ptr conn) : conn_{conn} { } - void on_hello(resp::array_type& v) noexcept override + void on_hello(array_type& v) noexcept override { auto f = [this](auto& req) { @@ -83,12 +83,12 @@ public: conn_->send(f); } - void on_simple_error(commands cmd, resp::simple_error_type& v) noexcept override + void on_simple_error(commands cmd, simple_error_type& v) noexcept override { std::cout << v << std::endl; } - void on_push(resp::array_type& v) noexcept override + void on_push(array_type& v) noexcept override { // TODO: Check the responses below. // {"subscribe", "channel", "1"} @@ -97,85 +97,85 @@ public: } // Blob string. - void on_get(resp::blob_string_type& s) noexcept override + void on_get(blob_string_type& s) noexcept override { check_equal(s, set_, "get (receiver)"); } - void on_hget(resp::blob_string_type& s) noexcept override + void on_hget(blob_string_type& s) noexcept override { check_equal(s, std::string{"value2"}, "hget (receiver)"); } - void on_lpop(resp::blob_string_type& s) noexcept override + void on_lpop(blob_string_type& s) noexcept override { check_equal(s, {"3"}, "lpop (receiver)"); } // Array - void on_lrange(resp::array_type& v) noexcept override + void on_lrange(array_type& v) noexcept override { check_equal(v, {"1", "2", "3", "4", "5", "6"}, "lrange (receiver)"); } - void on_lpop(resp::array_type& s) noexcept override + void on_lpop(array_type& s) noexcept override { check_equal(s, {"4", "5"}, "lpop(count) (receiver)"); } - void on_hgetall(resp::array_type& s) noexcept override + void on_hgetall(array_type& s) noexcept override { check_equal(s, {"field1", "value1", "field2", "value2"}, "hgetall (receiver)"); } - void on_hvals(resp::array_type& s) noexcept override + void on_hvals(array_type& s) noexcept override { check_equal(s, {"value1", "value2"}, "hvals (receiver)"); } - void on_zrange(resp::array_type& s) noexcept override + void on_zrange(array_type& s) noexcept override { check_equal(s, {"Marcelo"}, "zrange (receiver)"); } - void on_zrangebyscore(resp::array_type& s) noexcept override + void on_zrangebyscore(array_type& s) noexcept override { check_equal(s, {"Marcelo"}, "zrangebyscore (receiver)"); } - void on_smembers(resp::set_type& s) noexcept override + void on_smembers(set_type& s) noexcept override { check_equal(s, {"1", "2", "3"}, "smembers (receiver)"); } // Simple string - void on_set(resp::simple_string_type& s) noexcept override + void on_set(simple_string_type& s) noexcept override { check_equal(s, {"OK"}, "set (receiver)"); } - void on_quit(resp::simple_string_type& s) noexcept override + void on_quit(simple_string_type& s) noexcept override { check_equal(s, {"OK"}, "quit (receiver)"); } - void on_flushall(resp::simple_string_type& s) noexcept override + void on_flushall(simple_string_type& s) noexcept override { check_equal(s, {"OK"}, "flushall (receiver)"); } - void on_ltrim(resp::simple_string_type& s) noexcept override + void on_ltrim(simple_string_type& s) noexcept override { check_equal(s, {"OK"}, "ltrim (receiver)"); } // Number - void on_append(resp::number_type n) noexcept override + void on_append(number_type n) noexcept override { check_equal((int)n, 4, "append (receiver)"); } - void on_hset(resp::number_type n) noexcept override + void on_hset(number_type n) noexcept override { check_equal((int)n, 2, "hset (receiver)"); } - void on_rpush(resp::number_type n) noexcept override - { check_equal(n, (resp::number_type)std::size(list_), "rpush (receiver)"); } + void on_rpush(number_type n) noexcept override + { check_equal(n, (number_type)std::size(list_), "rpush (receiver)"); } - void on_del(resp::number_type n) noexcept override + void on_del(number_type n) noexcept override { check_equal((int)n, 1, "del (receiver)"); } - void on_llen(resp::number_type n) noexcept override + void on_llen(number_type n) noexcept override { check_equal((int)n, 6, "llen (receiver)"); } - void on_incr(resp::number_type n) noexcept override + void on_incr(number_type n) noexcept override { check_equal((int)n, 1, "incr (receiver)"); } - void on_publish(resp::number_type n) noexcept override + void on_publish(number_type n) noexcept override { check_equal((int)n, 1, "publish (receiver)"); } - void on_hincrby(resp::number_type n) noexcept override + void on_hincrby(number_type n) noexcept override { check_equal((int)n, 10, "hincrby (receiver)"); } - void on_zadd(resp::number_type n) noexcept override + void on_zadd(number_type n) noexcept override { check_equal((int)n, 1, "zadd (receiver)"); } - void on_zremrangebyscore(resp::number_type s) noexcept override + void on_zremrangebyscore(number_type s) noexcept override { check_equal((int)s, 1, "zremrangebyscore (receiver)"); } - void on_sadd(resp::number_type n) noexcept override + void on_sadd(number_type n) noexcept override { check_equal((int)n, 3, "sadd (receiver)"); } - void on_hdel(resp::number_type n) noexcept override + void on_hdel(number_type n) noexcept override { check_equal((int)n, 2, "hdel (receiver)"); } }; @@ -198,16 +198,16 @@ private: public: ping_receiver(std::shared_ptr conn) : conn_{conn} { } - void on_hello(resp::array_type& v) noexcept override + void on_hello(array_type& v) noexcept override { conn_->send([this](auto& req) { req.ping(); }); } - void on_ping(resp::simple_string_type& s) noexcept override + void on_ping(simple_string_type& s) noexcept override { check_equal(s, {"PONG"}, "ping"); conn_->send([this](auto& req) { req.quit(); }); } - void on_quit(resp::simple_string_type& s) noexcept override + void on_quit(simple_string_type& s) noexcept override { check_equal(s, {"OK"}, "quit"); } }; @@ -229,7 +229,7 @@ private: public: trans_receiver(std::shared_ptr conn) : conn_{conn} { } - void on_hello(resp::array_type& v) noexcept override + void on_hello(array_type& v) noexcept override { auto f = [this](auto& req) { @@ -245,7 +245,7 @@ public: conn_->send(f); } - void on_flushall(resp::simple_string_type& s) noexcept override + void on_flushall(simple_string_type& s) noexcept override { check_equal(s, {"OK"}, "flushall (transaction)"); } void @@ -253,28 +253,28 @@ public: { check_equal(result[0].command, commands::ping, "transaction (command)"); check_equal(result[0].depth, 1, "transaction (depth)"); - check_equal(result[0].type, resp::types::simple_string, "transaction (type)"); + check_equal(result[0].type, types::simple_string, "transaction (type)"); check_equal(result[0].expected_size, 1, "transaction (size)"); check_equal(result[1].command, commands::incr, "transaction (command)"); check_equal(result[1].depth, 1, "transaction (dept)h"); - check_equal(result[1].type, resp::types::number, "transaction (typ)e"); + check_equal(result[1].type, types::number, "transaction (typ)e"); check_equal(result[1].expected_size, 1, "transaction (size)"); check_equal(result[2].command, commands::publish, "transaction (command)"); check_equal(result[2].depth, 1, "transaction (depth)"); - check_equal(result[2].type, resp::types::number, "transaction (type)"); + check_equal(result[2].type, types::number, "transaction (type)"); check_equal(result[2].expected_size, 1, "transaction (size)"); result.clear(); } - void on_quit(resp::simple_string_type& s) noexcept override + void on_quit(simple_string_type& s) noexcept override { check_equal(s, {"OK"}, "quit"); } - void on_publish(resp::number_type n) noexcept override + void on_publish(number_type n) noexcept override { check_equal((int)n, 1, "publish (transaction)"); } - void on_ping(resp::simple_string_type& s) noexcept override + void on_ping(simple_string_type& s) noexcept override { check_equal(s, {"PONG"}, "ping"); conn_->send([this](auto& req) { req.quit(); }); @@ -315,49 +315,49 @@ test_list(net::ip::tcp::resolver::results_type const& results) std::string buffer; { // hello - resp::response_ignore res; - co_await resp::async_read(socket, buffer, res); + detail::response_ignore res; + co_await async_read(socket, buffer, res); } { // flushall - resp::response_simple_string res; - co_await resp::async_read(socket, buffer, res); + detail::response_simple_string res; + co_await async_read(socket, buffer, res); check_equal(res.result, {"OK"}, "flushall"); } { // rpush - resp::response_number res; - co_await resp::async_read(socket, buffer, res); + detail::response_number res; + co_await async_read(socket, buffer, res); check_equal(res.result, (long long int)6, "rpush"); } { // lrange - resp::response_basic_array res; - co_await resp::async_read(socket, buffer, res); + detail::response_basic_array res; + co_await async_read(socket, buffer, res); check_equal(res.result, list, "lrange-1"); } { // lrange - resp::response_basic_array res; - co_await resp::async_read(socket, buffer, res); + detail::response_basic_array res; + co_await async_read(socket, buffer, res); check_equal(res.result, std::vector{3, 4, 5}, "lrange-2"); } { // ltrim - resp::response_simple_string res; - co_await resp::async_read(socket, buffer, res); + detail::response_simple_string res; + co_await async_read(socket, buffer, res); check_equal(res.result, {"OK"}, "ltrim"); } { // lpop. Why a blob string instead of a number? - resp::response_blob_string res; - co_await resp::async_read(socket, buffer, res); + detail::response_blob_string res; + co_await async_read(socket, buffer, res); check_equal(res.result, {"3"}, "lpop"); } { // quit - resp::response_simple_string res; - co_await resp::async_read(socket, buffer, res); + detail::response_simple_string res; + co_await async_read(socket, buffer, res); check_equal(res.result, {"OK"}, "quit"); } } @@ -365,6 +365,7 @@ test_list(net::ip::tcp::resolver::results_type const& results) net::awaitable test_set(net::ip::tcp::resolver::results_type const& results) { + using namespace aedis::detail; auto ex = co_await this_coro::executor; // Tests whether the parser can handle payloads that contain the separator. @@ -392,50 +393,50 @@ test_set(net::ip::tcp::resolver::results_type const& results) std::string buffer; { // hello, flushall - resp::response_ignore res; - co_await resp::async_read(socket, buffer, res); - co_await resp::async_read(socket, buffer, res); + response_ignore res; + co_await async_read(socket, buffer, res); + co_await async_read(socket, buffer, res); } { // set - resp::response_simple_string res; - co_await resp::async_read(socket, buffer, res); + response_simple_string res; + co_await async_read(socket, buffer, res); check_equal(res.result, {"OK"}, "set1"); } { // get - resp::response_blob_string res; - co_await resp::async_read(socket, buffer, res); + response_blob_string res; + co_await async_read(socket, buffer, res); check_equal(res.result, test_bulk1, "get1"); } { // set - resp::response_simple_string res; - co_await resp::async_read(socket, buffer, res); + response_simple_string res; + co_await async_read(socket, buffer, res); check_equal(res.result, {"OK"}, "set1"); } { // get - resp::response_blob_string res; - co_await resp::async_read(socket, buffer, res); + response_blob_string res; + co_await async_read(socket, buffer, res); check_equal(res.result, test_bulk2, "get2"); } { // set - resp::response_simple_string res; - co_await resp::async_read(socket, buffer, res); + response_simple_string res; + co_await async_read(socket, buffer, res); check_equal(res.result, {"OK"}, "set3"); } { // get - resp::response_blob_string res; - co_await resp::async_read(socket, buffer, res); + response_blob_string res; + co_await async_read(socket, buffer, res); check_equal(res.result, std::string {}, "get3"); } { // quit - resp::response_simple_string res; - co_await resp::async_read(socket, buffer, res); + response_simple_string res; + co_await async_read(socket, buffer, res); check_equal(res.result, {"OK"}, "quit"); } } @@ -448,14 +449,15 @@ struct test_handler { } }; -net::awaitable simple_string() +net::awaitable test_simple_string() { + using namespace aedis::detail; { // Small string std::string buffer; std::string cmd {"+OK\r\n"}; test_tcp_socket ts {cmd}; - resp::response_simple_string res; - co_await resp::async_read(ts, buffer, res); + response_simple_string res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"OK"}, "simple_string"); //check_equal(res.attribute.value, {}, "simple_string (empty attribute)"); } @@ -464,8 +466,8 @@ net::awaitable simple_string() std::string buffer; std::string cmd {"+\r\n"}; test_tcp_socket ts {cmd}; - resp::response_simple_string res; - co_await resp::async_read(ts, buffer, res); + response_simple_string res; + co_await async_read(ts, buffer, res); check_equal(res.result, {}, "simple_string (empty)"); //check_equal(res.attribute.value, {}, "simple_string (empty attribute)"); } @@ -478,270 +480,281 @@ net::awaitable simple_string() // cmd += str; // cmd += "\r\n"; // test_tcp_socket ts {cmd}; - // resp::response_simple_string res; - // co_await resp::async_read(ts, buffer, res); + // response_simple_string res; + // co_await async_read(ts, buffer, res); // check_equal(res.result, str, "simple_string (large)"); // //check_equal(res.attribute.value, {}, "simple_string (empty attribute)"); //} } -net::awaitable number() +net::awaitable test_number() { + using namespace aedis::detail; std::string buffer; { // int std::string cmd {":-3\r\n"}; test_tcp_socket ts {cmd}; - resp::response_number res; - co_await resp::async_read(ts, buffer, res); + response_number res; + co_await async_read(ts, buffer, res); check_equal(res.result, (long long int)-3, "number (int)"); } { // unsigned std::string cmd {":3\r\n"}; test_tcp_socket ts {cmd}; - resp::response_number res; - co_await resp::async_read(ts, buffer, res); + response_number res; + co_await async_read(ts, buffer, res); check_equal(res.result, (long long int)3, "number (unsigned)"); } { // std::size_t std::string cmd {":1111111\r\n"}; test_tcp_socket ts {cmd}; - resp::response_number res; - co_await resp::async_read(ts, buffer, res); + response_number res; + co_await async_read(ts, buffer, res); check_equal(res.result, (long long int)1111111, "number (std::size_t)"); } } -net::awaitable array() +net::awaitable test_array() { + using namespace aedis::detail; std::string buffer; { // Dynamic std::string cmd {"*3\r\n$3\r\none\r\n$3\r\ntwo\r\n$5\r\nthree\r\n"}; test_tcp_socket ts {cmd}; - resp::response_array res; - co_await resp::async_read(ts, buffer, res); + response_array res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"one", "two", "three"}, "array (dynamic)"); } { // Static std::string cmd {"*3\r\n$3\r\none\r\n$3\r\ntwo\r\n$5\r\nthree\r\n"}; test_tcp_socket ts {cmd}; - resp::response_static_array res; - co_await resp::async_read(ts, buffer, res); + response_static_array res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"one", "two", "three"}, "array (static)"); } { // Static int std::string cmd {"*3\r\n$1\r\n1\r\n$1\r\n2\r\n$1\r\n3\r\n"}; test_tcp_socket ts {cmd}; - resp::response_static_array res; - co_await resp::async_read(ts, buffer, res); + response_static_array res; + co_await async_read(ts, buffer, res); check_equal(res.result, {1, 2, 3}, "array (int)"); } { std::string cmd {"*0\r\n"}; test_tcp_socket ts {cmd}; - resp::response_array res; - co_await resp::async_read(ts, buffer, res); + response_array res; + co_await async_read(ts, buffer, res); check_equal(res.result, {}, "array (empty)"); } } -net::awaitable blob_string() +net::awaitable test_blob_string() { + using namespace aedis::detail; std::string buffer; { std::string cmd {"$2\r\nhh\r\n"}; test_tcp_socket ts {cmd}; - resp::response_blob_string res; - co_await resp::async_read(ts, buffer, res); + response_blob_string res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"hh"}, "blob_string"); } { std::string cmd {"$26\r\nhhaa\aaaa\raaaaa\r\naaaaaaaaaa\r\n"}; test_tcp_socket ts {cmd}; - resp::response_blob_string res; - co_await resp::async_read(ts, buffer, res); + response_blob_string res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"hhaa\aaaa\raaaaa\r\naaaaaaaaaa"}, "blob_string (with separator)"); } { std::string cmd {"$0\r\n\r\n"}; test_tcp_socket ts {cmd}; - resp::response_blob_string res; - co_await resp::async_read(ts, buffer, res); + response_blob_string res; + co_await async_read(ts, buffer, res); check_equal(res.result, {}, "blob_string (size 0)"); } } -net::awaitable simple_error() +net::awaitable test_simple_error() { + using namespace aedis::detail; std::string buffer; { std::string cmd {"-Error\r\n"}; test_tcp_socket ts {cmd}; - resp::response_simple_error res; - co_await resp::async_read(ts, buffer, res); + response_simple_error res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"Error"}, "simple_error (message)"); } } -net::awaitable floating_point() +net::awaitable test_floating_point() { + using namespace aedis::detail; std::string buffer; { std::string cmd {",1.23\r\n"}; test_tcp_socket ts {cmd}; - resp::response_double res; - co_await resp::async_read(ts, buffer, res); + response_double res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"1.23"}, "double"); } { std::string cmd {",inf\r\n"}; test_tcp_socket ts {cmd}; - resp::response_double res; - co_await resp::async_read(ts, buffer, res); + response_double res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"inf"}, "double (inf)"); } { std::string cmd {",-inf\r\n"}; test_tcp_socket ts {cmd}; - resp::response_double res; - co_await resp::async_read(ts, buffer, res); + response_double res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"-inf"}, "double (-inf)"); } } -net::awaitable boolean() +net::awaitable test_boolean() { + using namespace aedis::detail; std::string buffer; { std::string cmd {"#f\r\n"}; test_tcp_socket ts {cmd}; - resp::response_bool res; - co_await resp::async_read(ts, buffer, res); + response_bool res; + co_await async_read(ts, buffer, res); check_equal(res.result, false, "bool (false)"); } { std::string cmd {"#t\r\n"}; test_tcp_socket ts {cmd}; - resp::response_bool res; - co_await resp::async_read(ts, buffer, res); + response_bool res; + co_await async_read(ts, buffer, res); check_equal(res.result, true, "bool (true)"); } } -net::awaitable blob_error() +net::awaitable test_blob_error() { + using namespace aedis::detail; std::string buffer; { std::string cmd {"!21\r\nSYNTAX invalid syntax\r\n"}; test_tcp_socket ts {cmd}; - resp::response_blob_error res; - co_await resp::async_read(ts, buffer, res); + response_blob_error res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"SYNTAX invalid syntax"}, "blob_error (message)"); } { std::string cmd {"!0\r\n\r\n"}; test_tcp_socket ts {cmd}; - resp::response_blob_error res; - co_await resp::async_read(ts, buffer, res); + response_blob_error res; + co_await async_read(ts, buffer, res); check_equal(res.result, {}, "blob_error (empty message)"); } } -net::awaitable verbatim_string() +net::awaitable test_verbatim_string() { + using namespace aedis::detail; std::string buffer; { std::string cmd {"=15\r\ntxt:Some string\r\n"}; test_tcp_socket ts {cmd}; - resp::response_verbatim_string res; - co_await resp::async_read(ts, buffer, res); + response_verbatim_string res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"txt:Some string"}, "verbatim_string"); } { std::string cmd {"=0\r\n\r\n"}; test_tcp_socket ts {cmd}; - resp::response_verbatim_string res; - co_await resp::async_read(ts, buffer, res); + response_verbatim_string res; + co_await async_read(ts, buffer, res); check_equal(res.result, {}, "verbatim_string (empty)"); } } -net::awaitable set() +net::awaitable test_set2() { + using namespace aedis::detail; std::string buffer; { std::string cmd {"~5\r\n+orange\r\n+apple\r\n+one\r\n+two\r\n+three\r\n"}; test_tcp_socket ts {cmd}; - resp::response_set res; - co_await resp::async_read(ts, buffer, res); + response_set res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"orange", "apple", "one", "two", "three"}, "set"); } { std::string cmd {"~5\r\n+orange\r\n+apple\r\n+one\r\n+two\r\n+three\r\n"}; test_tcp_socket ts {cmd}; - resp::response_set res; - co_await resp::async_read(ts, buffer, res); + response_set res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"orange", "apple", "one", "two", "three"}, "set (flat)"); } { std::string cmd {"~0\r\n"}; test_tcp_socket ts {cmd}; - resp::response_set res; - co_await resp::async_read(ts, buffer, res); + response_set res; + co_await async_read(ts, buffer, res); check_equal(res.result, {}, "set (empty)"); } } -net::awaitable map() +net::awaitable test_map() { + using namespace aedis::detail; std::string buffer; { std::string cmd {"%7\r\n$6\r\nserver\r\n$5\r\nredis\r\n$7\r\nversion\r\n$5\r\n6.0.9\r\n$5\r\nproto\r\n:3\r\n$2\r\nid\r\n:203\r\n$4\r\nmode\r\n$10\r\nstandalone\r\n$4\r\nrole\r\n$6\r\nmaster\r\n$7\r\nmodules\r\n*0\r\n"}; test_tcp_socket ts {cmd}; - resp::response_map res; - co_await resp::async_read(ts, buffer, res); + response_map res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"server", "redis", "version", "6.0.9", "proto", "3", "id", "203", "mode", "standalone", "role", "master", "modules"}, "map (flat)"); } { std::string cmd {"%0\r\n"}; test_tcp_socket ts {cmd}; - resp::response_map res; - co_await resp::async_read(ts, buffer, res); + response_map res; + co_await async_read(ts, buffer, res); check_equal(res.result, {}, "map (flat - empty)"); } } -net::awaitable streamed_string() +net::awaitable test_streamed_string() { + using namespace aedis::detail; std::string buffer; { std::string cmd {"$?\r\n;4\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n"}; test_tcp_socket ts {cmd}; - resp::response_streamed_string_part res; - co_await resp::async_read(ts, buffer, res); + response_streamed_string_part res; + co_await async_read(ts, buffer, res); check_equal(res.result, {"Hello word"}, "streamed string"); } { std::string cmd {"$?\r\n;0\r\n"}; test_tcp_socket ts {cmd}; - resp::response_array res; - co_await resp::async_read(ts, buffer, res); + response_array res; + co_await async_read(ts, buffer, res); check_equal(res.result, {}, "streamed string (empty)"); } } @@ -752,24 +765,24 @@ net::awaitable offline() //{ // std::string cmd {"|1\r\n+key-popularity\r\n%2\r\n$1\r\na\r\n,0.1923\r\n$1\r\nb\r\n,0.0012\r\n"}; // test_tcp_socket ts {cmd}; - // resp::response_array res; - // co_await resp::async_read(ts, buffer, res); + // response_array res; + // co_await async_read(ts, buffer, res); // check_equal(res.result, {"key-popularity", "a", "0.1923", "b", "0.0012"}, "attribute"); //} //{ // std::string cmd {">4\r\n+pubsub\r\n+message\r\n+foo\r\n+bar\r\n"}; // test_tcp_socket ts {cmd}; - // resp::response_array res; - // co_await resp::async_read(ts, buffer, res); + // response_array res; + // co_await async_read(ts, buffer, res); // check_equal(res.result, {"pubsub", "message", "foo", "bar"}, "push type"); //} //{ // std::string cmd {">0\r\n"}; // test_tcp_socket ts {cmd}; - // resp::response_array res; - // co_await resp::async_read(ts, buffer, res); + // response_array res; + // co_await async_read(ts, buffer, res); // check_equal(res.result, {}, "push type (empty)"); //} } @@ -780,17 +793,17 @@ int main(int argc, char* argv[]) tcp::resolver resv(ioc); auto const results = resv.resolve("127.0.0.1", "6379"); - co_spawn(ioc, simple_string(), net::detached); - co_spawn(ioc, number(), net::detached); - co_spawn(ioc, array(), net::detached); - co_spawn(ioc, blob_string(), net::detached); - co_spawn(ioc, simple_error(), net::detached); - co_spawn(ioc, floating_point(), net::detached); - co_spawn(ioc, boolean(), net::detached); - co_spawn(ioc, blob_error(), net::detached); - co_spawn(ioc, verbatim_string(), net::detached); - co_spawn(ioc, set(), net::detached); - co_spawn(ioc, map(), net::detached); + co_spawn(ioc, test_simple_string(), net::detached); + co_spawn(ioc, test_number(), net::detached); + co_spawn(ioc, test_array(), net::detached); + co_spawn(ioc, test_blob_string(), net::detached); + co_spawn(ioc, test_simple_error(), net::detached); + co_spawn(ioc, test_floating_point(), net::detached); + co_spawn(ioc, test_boolean(), net::detached); + co_spawn(ioc, test_blob_error(), net::detached); + co_spawn(ioc, test_verbatim_string(), net::detached); + co_spawn(ioc, test_set2(), net::detached); + co_spawn(ioc, test_map(), net::detached); co_spawn(ioc, test_list(results), net::detached); co_spawn(ioc, test_set(results), net::detached);