Seastar
High performance C++ framework for concurrent servers
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
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
38namespace seastar {
39
40namespace json {
41
42SEASTAR_MODULE_EXPORT_BEGIN
43
53protected:
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;
70public:
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
101template<class T>
103public:
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 }
149private:
150 T _value;
151};
152
159template<class T>
161public:
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
195class jsonable {
196public:
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
214 return s.write(to_json());
215 }
216};
217
228struct 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
273struct json_void : public jsonable{
274 virtual std::string to_json() const {
275 return "";
276 }
277
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
331template<typename Container, typename Func>
332requires requires (Container c, Func aa, output_stream<char> s) { { formatter::write(s, aa(*c.begin())) } -> std::same_as<future<>>; }
333std::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
359template<class T>
360std::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
370SEASTAR_MODULE_EXPORT_END
371}
372
373}
A representation of a possibly not-yet-computed value.
Definition: future.hh:1240
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
json_list & operator=(const C &list)
Definition: json_elements.hh:182
void push(const T &element)
Definition: json_elements.hh:167
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
future do_for_each(Iterator begin, Sentinel end, AsyncAction action) noexcept
Call a function for each item in a range, sequentially (iterator version).
Definition: loop.hh:465
auto do_with(T1 &&rv1, T2 &&rv2, More &&... more) noexcept
Definition: do_with.hh:135
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