29#include <unordered_map>
35#include <seastar/core/loop.hh>
36#include <seastar/core/sstring.hh>
37#include <seastar/core/iostream.hh>
38#include <seastar/util/modules.hh>
45concept is_map =
requires {
46 typename T::mapped_type;
50concept is_pair_like =
requires {
51 typename std::tuple_size<T>::type;
52 requires std::tuple_size_v<T> == 2;
56concept is_string_like =
57 std::convertible_to<const T&, std::string_view> &&
59 { s.data() } -> std::same_as<char*>;
74typedef struct tm date_time;
86 static sstring begin(state);
87 static sstring end(state);
89 template<
internal::is_pair_like T>
90 static sstring to_json(state s,
const T& p) {
91 auto& [key, value] = p;
92 return s == state::array ?
93 "{" + to_json(state::none, p) +
"}" :
94 to_json(key) +
":" + to_json(value);
97 template<
typename Iterator,
typename Sentinel>
98 static sstring to_json(state s, Iterator i, Sentinel e) {
99 std::stringstream res;
106 res << to_json(s, *i++);
114 static sstring to_json(state,
const T& t) {
118 template<
internal::is_pair_like T>
120 if (s == state::array) {
127 auto& [key, value] = p;
128 return stream.write(to_json(key) +
":").then([&value, &
stream] {
129 return write(
stream, value);
134 template<
internal::is_pair_like T>
136 if (s == state::array) {
143 auto& [key, value] = p;
144 return stream.write(to_json(key) +
":").then([&
stream, value] {
145 return write(
stream, value);
150 template<
typename Iterator,
typename Sentinel>
153 return stream.write(begin(s)).then([&first, &
stream, s, i, e] {
154 using ref_t = std::iter_reference_t<Iterator>;
156 auto f = (first) ? make_ready_future<>() :
stream.write(
",");
158 if constexpr (std::is_lvalue_reference_v<ref_t>) {
159 return f.then([&m, &
stream, s] {
160 return write(
stream, s, m);
163 using value_t = std::iter_value_t<Iterator>;
164 return f.then([m = std::forward<value_t>(m), &
stream, s] {
165 return write(
stream, s, m);
169 return stream.write(end(s));
231 static sstring
to_json(
const char* str,
size_t len);
253 template<std::ranges::input_range Range>
254 requires (!internal::is_string_like<Range>)
256 if constexpr (internal::is_map<Range>) {
257 return to_json(state::map, std::ranges::begin(range), std::ranges::end(range));
259 return to_json(state::array, std::ranges::begin(range), std::ranges::end(range));
292 return s.write(to_json(str));
301 return s.write(to_json(n));
310 return s.write(to_json(n));
319 return s.write(to_json(f));
328 return s.write(to_json(d));
337 return s.write(to_json(str));
346 return s.write(to_json(d));
358 template<std::ranges::input_range Range>
359 requires (!internal::is_string_like<Range>)
361 return do_with(std::move(range), [&s] (
const auto& range) {
362 if constexpr (internal::is_map<Range>) {
363 return write(s, state::map, std::ranges::begin(range), std::ranges::end(range));
365 return write(s, state::array, std::ranges::begin(range), std::ranges::end(range));
376 return s.write(to_json(d));
384 template <std::derived_from<jsonable> Jsonable>
386 return do_with(std::move(obj), [&s] (
const auto& obj) {
397 return s.write(to_json(l));
A representation of a possibly not-yet-computed value.
Definition: future.hh:1240
Result then(Func &&func) noexcept
Schedule a block of code to run when the future is ready.
Definition: future.hh:1425
Definition: json_elements.hh:195
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