Seastar
High performance C++ framework for concurrent servers
formatter.hh
1 /*
2  * This file is open source software, licensed to you under the terms
3  * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4  * distributed with this work for additional information regarding copyright
5  * ownership. You may not use this file except in compliance with the License.
6  *
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an
13  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14  * KIND, either express or implied. See the License for the
15  * specific language governing permissions and limitations
16  * under the License.
17  */
18 /*
19  * Copyright 2015 Cloudius Systems
20  */
21 
22 #pragma once
23 
24 #ifndef SEASTAR_MODULE
25 #include <string>
26 #include <vector>
27 #include <unordered_map>
28 #include <map>
29 #include <time.h>
30 #include <sstream>
31 #endif
32 
33 #include <seastar/core/loop.hh>
34 #include <seastar/core/sstring.hh>
35 #include <seastar/core/iostream.hh>
36 #include <seastar/util/modules.hh>
37 
38 namespace seastar {
39 
40 namespace json {
41 
42 SEASTAR_MODULE_EXPORT
43 class jsonable;
44 
45 typedef struct tm date_time;
46 
52 SEASTAR_MODULE_EXPORT
53 class formatter {
54  enum class state {
55  none, array, map
56  };
57  static sstring begin(state);
58  static sstring end(state);
59 
60  template<typename K, typename V>
61  static sstring to_json(state s, const std::pair<K, V>& p) {
62  return s == state::array ?
63  "{" + to_json(state::none, p) + "}" :
64  to_json(p.first) + ":" + to_json(p.second);
65  }
66 
67  template<typename Iter>
68  static sstring to_json(state s, Iter i, Iter e) {
69  std::stringstream res;
70  res << begin(s);
71  size_t n = 0;
72  while (i != e) {
73  if (n++ != 0) {
74  res << ",";
75  }
76  res << to_json(s, *i++);
77  }
78  res << end(s);
79  return res.str();
80  }
81 
82  // fallback template
83  template<typename T>
84  static sstring to_json(state, const T& t) {
85  return to_json(t);
86  }
87 
88  template<typename K, typename V>
89  static future<> write(output_stream<char>& stream, state s, const std::pair<K, V>& p) {
90  if (s == state::array) {
91  return stream.write("{").then([&stream, &p] {
92  return write(stream, state::none, p).then([&stream] {
93  return stream.write("}");
94  });
95  });
96  } else {
97  return stream.write(to_json(p.first) + ":").then([&p, &stream] {
98  return write(stream, p.second);
99  });
100  }
101  }
102 
103  template<typename Iter>
104  static future<> write(output_stream<char>& stream, state s, Iter i, Iter e) {
105  return do_with(true, [&stream, s, i, e] (bool& first) {
106  return stream.write(begin(s)).then([&first, &stream, s, i, e] {
107  return do_for_each(i, e, [&first, &stream] (auto& m) {
108  auto f = (first) ? make_ready_future<>() : stream.write(",");
109  first = false;
110  return f.then([&m, &stream] {
111  return write(stream, m);
112  });
113  }).then([&stream, s] {
114  return stream.write(end(s));
115  });
116  });
117  });
118  }
119 
120  // fallback template
121  template<typename T>
122  static future<> write(output_stream<char>& stream, state, const T& t) {
123  return stream.write(to_json(t));
124  }
125 
126 public:
127 
133  static sstring to_json(const sstring& str);
134 
140  static sstring to_json(int n);
141 
147  static sstring to_json(unsigned n);
148 
154  static sstring to_json(long n);
155 
161  static sstring to_json(float f);
162 
168  static sstring to_json(double d);
169 
176  static sstring to_json(const char* str, size_t len);
177 
184  static sstring to_json(const char* str);
185 
191  static sstring to_json(bool d);
192 
198  template<typename... Args>
199  static sstring to_json(const std::vector<Args...>& vec) {
200  return to_json(state::array, vec.begin(), vec.end());
201  }
202 
203  template<typename... Args>
204  static sstring to_json(const std::map<Args...>& map) {
205  return to_json(state::map, map.begin(), map.end());
206  }
207 
208  template<typename... Args>
209  static sstring to_json(const std::unordered_map<Args...>& map) {
210  return to_json(state::map, map.begin(), map.end());
211  }
212 
218  static sstring to_json(const date_time& d);
219 
225  static sstring to_json(const jsonable& obj);
226 
232  static sstring to_json(unsigned long l);
233 
234 
235 
241  static future<> write(output_stream<char>& s, const sstring& str) {
242  return s.write(to_json(str));
243  }
244 
250  static future<> write(output_stream<char>& s, int n) {
251  return s.write(to_json(n));
252  }
253 
259  static future<> write(output_stream<char>& s, long n) {
260  return s.write(to_json(n));
261  }
262 
268  static future<> write(output_stream<char>& s, float f) {
269  return s.write(to_json(f));
270  }
271 
277  static future<> write(output_stream<char>& s, double d) {
278  return s.write(to_json(d));
279  }
280 
286  static future<> write(output_stream<char>& s, const char* str) {
287  return s.write(to_json(str));
288  }
289 
295  static future<> write(output_stream<char>& s, bool d) {
296  return s.write(to_json(d));
297  }
298 
304  template<typename... Args>
305  static future<> write(output_stream<char>& s, const std::vector<Args...>& vec) {
306  return write(s, state::array, vec.begin(), vec.end());
307  }
308 
309  template<typename... Args>
310  static future<> write(output_stream<char>& s, const std::map<Args...>& map) {
311  return write(s, state::map, map.begin(), map.end());
312  }
313 
314  template<typename... Args>
315  static future<> write(output_stream<char>& s, const std::unordered_map<Args...>& map) {
316  return write(s, state::map, map.begin(), map.end());
317  }
318 
324  static future<> write(output_stream<char>& s, const date_time& d) {
325  return s.write(to_json(d));
326  }
327 
333  static future<> write(output_stream<char>& s, const jsonable& obj) {
334  return s.write(to_json(obj));
335  }
336 
342  static future<> write(output_stream<char>& s, unsigned long l) {
343  return s.write(to_json(l));
344  }
345 };
346 
347 }
348 
349 }
Result then(Func &&func) noexcept
Schedule a block of code to run when the future is ready.
Definition: future.hh:1410
Definition: formatter.hh:53
static sstring to_json(double d)
static future write(output_stream< char > &s, const date_time &d)
Definition: formatter.hh:324
static future write(output_stream< char > &s, double d)
Definition: formatter.hh:277
static future write(output_stream< char > &s, long n)
Definition: formatter.hh:259
static future write(output_stream< char > &s, const jsonable &obj)
Definition: formatter.hh:333
static future write(output_stream< char > &s, unsigned long l)
Definition: formatter.hh:342
static future write(output_stream< char > &s, const std::vector< Args... > &vec)
Definition: formatter.hh:305
static sstring to_json(const sstring &str)
static future write(output_stream< char > &s, float f)
Definition: formatter.hh:268
static sstring to_json(long n)
static sstring to_json(const date_time &d)
static sstring to_json(const std::vector< Args... > &vec)
Definition: formatter.hh:199
static sstring to_json(int n)
static future write(output_stream< char > &s, const sstring &str)
Definition: formatter.hh:241
static future write(output_stream< char > &s, bool d)
Definition: formatter.hh:295
static sstring to_json(unsigned long l)
static future write(output_stream< char > &s, const char *str)
Definition: formatter.hh:286
static future write(output_stream< char > &s, int n)
Definition: formatter.hh:250
static sstring to_json(const jsonable &obj)
static sstring to_json(bool d)
static sstring to_json(unsigned n)
static sstring to_json(const char *str)
static sstring to_json(float f)
static sstring to_json(const char *str, size_t len)
Definition: json_elements.hh:195
Definition: stream.hh:61
auto do_with(T1 &&rv1, T2 &&rv2, More &&... more) noexcept
Definition: do_with.hh:135
future do_for_each(Iterator begin, Iterator end, AsyncAction action) noexcept
Call a function for each item in a range, sequentially (iterator version).
Definition: loop.hh:462
Seastar API namespace.
Definition: abort_on_ebadf.hh:26