Seastar
High performance C++ framework for concurrent servers
json_elements.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 <time.h>
28 #include <sstream>
29 #endif
30 
31 #include <seastar/core/do_with.hh>
32 #include <seastar/core/loop.hh>
33 #include <seastar/json/formatter.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_BEGIN
43 
53 protected:
57  json_base_element() noexcept
58  : _mandatory(false), _set(false) {
59  }
60 
61  json_base_element(const json_base_element& o) noexcept = default;
62  json_base_element& operator=(const json_base_element& o) noexcept {
63  // Names and mandatory are never changed after creation
64  _set = o._set;
65  return *this;
66  }
67 
69  json_base_element& operator=(json_base_element&&) = delete;
70 public:
71  virtual ~json_base_element() = default;
78  virtual bool is_verify() noexcept {
79  return !(_mandatory && !_set);
80  }
81 
87  virtual std::string to_string() = 0;
88 
89  virtual future<> write(output_stream<char>& s) const = 0;
90  std::string _name;
91  bool _mandatory;
92  bool _set;
93 };
94 
101 template<class T>
103 public:
104 
111  json_element &operator=(const T& new_value) {
112  _value = new_value;
113  _set = true;
114  return *this;
115  }
122  template<class C>
123  json_element &operator=(const C& new_value) {
124  _value = new_value;
125  _set = true;
126  return *this;
127  }
132  const T& operator()() const noexcept {
133  return _value;
134  }
135 
141  virtual std::string to_string() override
142  {
143  return formatter::to_json(_value);
144  }
145 
146  virtual future<> write(output_stream<char>& s) const override {
147  return formatter::write(s, _value);
148  }
149 private:
150  T _value;
151 };
152 
159 template<class T>
160 class json_list : public json_base_element {
161 public:
162 
167  void push(const T& element) {
168  _set = true;
169  _elements.push_back(element);
170  }
171 
172  virtual std::string to_string() override
173  {
174  return formatter::to_json(_elements);
175  }
176 
181  template<class C>
182  json_list& operator=(const C& list) {
183  _elements.clear();
184  for (auto i : list) {
185  push(i);
186  }
187  return *this;
188  }
189  virtual future<> write(output_stream<char>& s) const override {
190  return formatter::write(s, _elements);
191  }
192  std::vector<T> _elements;
193 };
194 
195 class jsonable {
196 public:
197  jsonable() = default;
198  jsonable(const jsonable&) = default;
199  jsonable& operator=(const jsonable&) = default;
200  virtual ~jsonable() = default;
205  virtual std::string to_json() const = 0;
206 
213  virtual future<> write(output_stream<char>& s) const {
214  return s.write(to_json());
215  }
216 };
217 
228 struct json_base : public jsonable {
229 
230  virtual ~json_base() = default;
231 
232  json_base() = default;
233 
234  json_base(const json_base&) = delete;
235 
236  json_base operator=(const json_base&) = delete;
237 
242  virtual std::string to_json() const;
243 
248 
253  virtual bool is_verify() const;
254 
261  virtual void add(json_base_element* element, std::string name,
262  bool mandatory = false);
263 
264  std::vector<json_base_element*> _elements;
265 };
266 
273 struct json_void : public jsonable{
274  virtual std::string to_json() const {
275  return "";
276  }
277 
281  virtual future<> write(output_stream<char>& s) const {
282  return s.close();
283  }
284 };
285 
286 
300  sstring _res;
301  std::function<future<>(output_stream<char>&&)> _body_writer;
302  json_return_type(std::function<future<>(output_stream<char>&&)>&& body_writer) : _body_writer(std::move(body_writer)) {
303  }
304  template<class T>
305  json_return_type(const T& res) {
306  _res = formatter::to_json(res);
307  }
308 
309  json_return_type(json_return_type&& o) noexcept : _res(std::move(o._res)), _body_writer(std::move(o._body_writer)) {
310  }
311  json_return_type& operator=(json_return_type&& o) noexcept {
312  if (this != &o) {
313  _res = std::move(o._res);
314  _body_writer = std::move(o._body_writer);
315  }
316  return *this;
317  }
318 
319  json_return_type(const json_return_type&) = default;
320  json_return_type& operator=(const json_return_type&) = default;
321 };
322 
331 template<typename Container, typename Func>
332 SEASTAR_CONCEPT( requires requires (Container c, Func aa, output_stream<char> s) { { formatter::write(s, aa(*c.begin())) } -> std::same_as<future<>>; } )
333 std::function<future<>(output_stream<char>&&)> stream_range_as_array(Container val, Func fun) {
334  return [val = std::move(val), fun = std::move(fun)](output_stream<char>&& s) mutable {
335  return do_with(output_stream<char>(std::move(s)), Container(std::move(val)), Func(std::move(fun)), true, [](output_stream<char>& s, const Container& val, const Func& f, bool& first){
336  return s.write("[").then([&val, &s, &first, &f] () {
337  return do_for_each(val, [&s, &first, &f](const typename Container::value_type& v){
338  auto fut = first ? make_ready_future<>() : s.write(", ");
339  first = false;
340  return fut.then([&s, &f, &v]() {
341  return formatter::write(s, f(v));
342  });
343  });
344  }).then([&s](){
345  return s.write("]");
346  }).finally([&s] {
347  return s.close();
348  });
349  });
350  };
351 }
352 
359 template<class T>
360 std::function<future<>(output_stream<char>&&)> stream_object(T val) {
361  return [val = std::move(val)](output_stream<char>&& s) mutable {
362  return do_with(output_stream<char>(std::move(s)), T(std::move(val)), [](output_stream<char>& s, const T& val){
363  return formatter::write(s, val).finally([&s] {
364  return s.close();
365  });
366  });
367  };
368 }
369 
370 SEASTAR_MODULE_EXPORT_END
371 }
372 
373 }
Definition: json_elements.hh:52
json_base_element() noexcept
Definition: json_elements.hh:57
virtual bool is_verify() noexcept
Definition: json_elements.hh:78
virtual std::string to_string()=0
Definition: json_elements.hh:102
json_element & operator=(const C &new_value)
Definition: json_elements.hh:123
const T & operator()() const noexcept
Definition: json_elements.hh:132
json_element & operator=(const T &new_value)
Definition: json_elements.hh:111
virtual std::string to_string() override
Definition: json_elements.hh:141
Definition: json_elements.hh:160
void push(const T &element)
Definition: json_elements.hh:167
json_list & operator=(const C &list)
Definition: json_elements.hh:182
virtual std::string to_string() override
Definition: json_elements.hh:172
Definition: json_elements.hh:195
virtual future write(output_stream< char > &s) const
write an object to the output stream
Definition: json_elements.hh:213
virtual std::string to_json() const =0
future close() noexcept
Definition: iostream-impl.hh:496
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
Definition: json_elements.hh:228
virtual bool is_verify() const
virtual future write(output_stream< char > &) const
write to an output stream
virtual std::string to_json() const
virtual void add(json_base_element *element, std::string name, bool mandatory=false)
Definition: json_elements.hh:299
Definition: json_elements.hh:273
virtual future write(output_stream< char > &s) const
write to an output stream
Definition: json_elements.hh:281
virtual std::string to_json() const
Definition: json_elements.hh:274