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#endif
28
29#include <seastar/core/chunked_fifo.hh>
30#include <seastar/core/do_with.hh>
31#include <seastar/core/iostream.hh>
32#include <seastar/core/loop.hh>
33#include <seastar/core/sstring.hh>
34#include <seastar/json/formatter.hh>
35#include <seastar/util/modules.hh>
36
37namespace seastar {
38
39namespace json {
40
41SEASTAR_MODULE_EXPORT_BEGIN
42
52protected:
57 : _mandatory(false), _set(false) {
58 }
59
60 json_base_element(const json_base_element& o) noexcept = default;
61 json_base_element& operator=(const json_base_element& o) noexcept {
62 // Names and mandatory are never changed after creation
63 _set = o._set;
64 return *this;
65 }
66
68 json_base_element& operator=(json_base_element&&) = delete;
69public:
70 virtual ~json_base_element() = default;
77 virtual bool is_verify() noexcept {
78 return !(_mandatory && !_set);
79 }
80
86 virtual std::string to_string() = 0;
87
88 virtual future<> write(output_stream<char>& s) const = 0;
89 std::string _name;
90 bool _mandatory;
91 bool _set;
92};
93
100template<class T>
102public:
103
110 json_element &operator=(const T& new_value) {
111 _value = new_value;
112 _set = true;
113 return *this;
114 }
121 template<class C>
122 json_element &operator=(const C& new_value) {
123 _value = new_value;
124 _set = true;
125 return *this;
126 }
131 const T& operator()() const noexcept {
132 return _value;
133 }
134
140 virtual std::string to_string() override
141 {
142 return formatter::to_json(_value);
143 }
144
145 virtual future<> write(output_stream<char>& s) const override {
146 return formatter::write(s, _value);
147 }
148private:
149 T _value;
150};
151
160template <class T, class Container>
162public:
163
168 void push(const T& element) {
169 _set = true;
170 _elements.push_back(element);
171 }
172
177 void push(T&& element) {
178 _set = true;
179 _elements.push_back(std::move(element));
180 }
181
182 virtual std::string to_string() override
183 {
184 return formatter::to_json(_elements);
185 }
186
191 template<class C>
193 _elements.clear();
194 for (auto i : list) {
195 push(i);
196 }
197 return *this;
198 }
199 virtual future<> write(output_stream<char>& s) const override {
200 return formatter::write(s, _elements);
201 }
202
203 Container _elements;
204};
205
206template <typename T>
207using json_list = json_list_template<T, std::vector<T>>;
208
209template <typename T>
210using json_chunked_list = json_list_template<T, seastar::chunked_fifo<T>>;
211
212class jsonable {
213public:
214 jsonable() = default;
215 jsonable(const jsonable&) = default;
216 jsonable& operator=(const jsonable&) = default;
217 virtual ~jsonable() = default;
222 virtual std::string to_json() const = 0;
223
231 return s.write(to_json());
232 }
233};
234
245struct json_base : public jsonable {
246
247 virtual ~json_base() = default;
248
249 json_base() = default;
250
251 json_base(const json_base&) = delete;
252
253 json_base operator=(const json_base&) = delete;
254
259 virtual std::string to_json() const;
260
265
270 virtual bool is_verify() const;
271
278 virtual void add(json_base_element* element, std::string name,
279 bool mandatory = false);
280
281 std::vector<json_base_element*> _elements;
282};
283
290struct json_void : public jsonable{
291 virtual std::string to_json() const {
292 return "";
293 }
294
299 return s.close();
300 }
301};
302
303
317 sstring _res;
318 std::function<future<>(output_stream<char>&&)> _body_writer;
319 json_return_type(std::function<future<>(output_stream<char>&&)>&& body_writer) : _body_writer(std::move(body_writer)) {
320 }
321 template<class T>
322 json_return_type(const T& res) {
323 _res = formatter::to_json(res);
324 }
325
326 json_return_type(json_return_type&& o) noexcept : _res(std::move(o._res)), _body_writer(std::move(o._body_writer)) {
327 }
328 json_return_type& operator=(json_return_type&& o) noexcept {
329 if (this != &o) {
330 _res = std::move(o._res);
331 _body_writer = std::move(o._body_writer);
332 }
333 return *this;
334 }
335
336 json_return_type(const json_return_type&) = default;
337 json_return_type& operator=(const json_return_type&) = default;
338};
339
348template<typename Container, typename Func>
349requires requires (Container c, Func aa, output_stream<char> s) { { formatter::write(s, aa(*c.begin())) } -> std::same_as<future<>>; }
350std::function<future<>(output_stream<char>&&)> stream_range_as_array(Container val, Func fun) {
351 return [val = std::move(val), fun = std::move(fun)](output_stream<char>&& s) mutable {
352 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){
353 return s.write("[").then([&val, &s, &first, &f] () {
354 return do_for_each(val, [&s, &first, &f](const typename Container::value_type& v){
355 auto fut = first ? make_ready_future<>() : s.write(", ");
356 first = false;
357 return fut.then([&s, &f, &v]() {
358 return formatter::write(s, f(v));
359 });
360 });
361 }).then([&s](){
362 return s.write("]");
363 }).finally([&s] {
364 return s.close();
365 });
366 });
367 };
368}
369
376template<class T>
377std::function<future<>(output_stream<char>&&)> stream_object(T val) {
378 return [val = std::move(val)](output_stream<char>&& s) mutable {
379 return do_with(output_stream<char>(std::move(s)), T(std::move(val)), [](output_stream<char>& s, T& val){
380 return formatter::write(s, std::move(val)).finally([&s] {
381 return s.close();
382 });
383 });
384 };
385}
386
387SEASTAR_MODULE_EXPORT_END
388}
389
390}
A representation of a possibly not-yet-computed value.
Definition: future.hh:1197
Definition: json_elements.hh:51
json_base_element() noexcept
Definition: json_elements.hh:56
virtual bool is_verify() noexcept
Definition: json_elements.hh:77
virtual std::string to_string()=0
Definition: json_elements.hh:101
json_element & operator=(const C &new_value)
Definition: json_elements.hh:122
const T & operator()() const noexcept
Definition: json_elements.hh:131
json_element & operator=(const T &new_value)
Definition: json_elements.hh:110
virtual std::string to_string() override
Definition: json_elements.hh:140
Definition: json_elements.hh:161
virtual std::string to_string() override
Definition: json_elements.hh:182
json_list_template & operator=(const C &list)
Definition: json_elements.hh:192
void push(const T &element)
Definition: json_elements.hh:168
void push(T &&element)
Definition: json_elements.hh:177
Definition: json_elements.hh:212
virtual future write(output_stream< char > &s) const
write an object to the output stream
Definition: json_elements.hh:230
virtual std::string to_json() const =0
future close() noexcept
Definition: iostream-impl.hh:497
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:466
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:245
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:316
Definition: json_elements.hh:290
virtual future write(output_stream< char > &s) const
write to an output stream
Definition: json_elements.hh:298
virtual std::string to_json() const
Definition: json_elements.hh:291