Aedis 0.0.1  
Low level Redis client library
serialization.cpp
1 /* Copyright (c) 2019 Marcelo Zimbres Silva (mzimbres@gmail.com)
2  *
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
6  */
7 
8 #include <string>
9 #include <iostream>
10 #include <charconv>
11 
12 #include <aedis/aedis.hpp>
13 #include <aedis/src.hpp>
14 
15 #include "lib/net_utils.hpp"
16 
17 namespace resp3 = aedis::resp3;
20 using resp3::adapt;
21 
22 namespace net = aedis::net;
23 using net::async_write;
24 using net::buffer;
25 using net::dynamic_buffer;
26 
27 // Define the to_string and from_string functions for your own data
28 // types.
29 
30 // The struct we would like to store in redis using our own
31 // serialization.
32 struct mydata {
33  int a;
34  int b;
35 };
36 
37 // Serializes to Tab Separated Value (TSV).
38 std::string to_string(mydata const& obj)
39 {
40  return std::to_string(obj.a) + '\t' + std::to_string(obj.b);
41 }
42 
43 // Deserializes TSV.
44 void
45 from_string(
46  mydata& obj,
47  char const* data,
48  std::size_t size,
49  std::error_code& ec)
50 {
51  auto const* end = data + size;
52  auto const* pos = std::find(data, end, '\t');
53  assert(pos != end); // Or use your own error code.
54 
55  auto const res1 = std::from_chars(data, pos, obj.a);
56  if (res1.ec != std::errc()) {
57  ec = std::make_error_code(res1.ec);
58  return;
59  }
60 
61  auto const res2 = std::from_chars(pos + 1, end, obj.b);
62  if (res2.ec != std::errc()) {
63  ec = std::make_error_code(res2.ec);
64  return;
65  }
66 }
67 
68 net::awaitable<void> serialization()
69 {
70  try {
71  auto socket = co_await connect();
72 
73  mydata obj{21, 22};
74 
75  std::string request;
76  auto sr = make_serializer(request);
77  sr.push(command::hello, 3);
78  sr.push(command::flushall);
79  sr.push(command::set, "key", obj);
80  sr.push(command::get, "key");
81  sr.push(command::quit);
82  co_await async_write(socket, buffer(request));
83 
84  // The response.
85  mydata get;
86 
87  // Reads the responses.
88  std::string buffer;
89  co_await resp3::async_read(socket, dynamic_buffer(buffer)); // hello
90  co_await resp3::async_read(socket, dynamic_buffer(buffer)); // flushall
91  co_await resp3::async_read(socket, dynamic_buffer(buffer)); // set
92  co_await resp3::async_read(socket, dynamic_buffer(buffer), adapt(get));
93  co_await resp3::async_read(socket, dynamic_buffer(buffer)); // quit
94 
95  // Print the responses.
96  std::cout << "get: a = " << get.a << ", b = " << get.b << "\n";
97 
98  } catch (std::exception const& e) {
99  std::cerr << e.what() << std::endl;
100  exit(EXIT_FAILURE);
101  }
102 }
103 
104 int main()
105 {
106  net::io_context ioc;
107  co_spawn(ioc, serialization(), net::detached);
108  ioc.run();
109 }
auto adapt() noexcept
Creates a void response adapter.
Definition: adapt.hpp:29
std::error_code make_error_code(error e)
Converts an error in an std::error_code object.
Definition: error.hpp:60
resp3::serializer< std::string, command > make_serializer(std::basic_string< CharT, Traits, Allocator > &storage)
Creates a serializer for a std::string.
Definition: command.hpp:465
char const * to_string(command c)
Converts a command to a string.
Definition: command.ipp:13
command
Redis commands.
Definition: command.hpp:26
@ get
https://redis.io/commands/get