userver: userver/formats/yaml/inline.hpp Source File
Loading...
Searching...
No Matches
inline.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/formats/yaml/inline.hpp
4/// @brief Inline value builders
5/// @ingroup userver_universal
6
7#include <chrono>
8#include <cstddef>
9#include <string>
10#include <string_view>
11#include <type_traits>
12#include <utility>
13
14#include <userver/formats/yaml/value.hpp>
15#include <userver/formats/yaml/value_builder.hpp>
16
17USERVER_NAMESPACE_BEGIN
18
19namespace formats::yaml {
20
21namespace impl {
22
23template <typename T>
24concept InlineValue =
25 std::is_same_v<T, std::nullptr_t> || std::is_integral_v<T> || std::is_same_v<T, float> ||
26 std::is_same_v<T, double> || std::is_convertible_v<T, std::string_view> || std::is_same_v<T, formats::yaml::Value>;
27
28class InlineObjectBuilder {
29public:
30 InlineObjectBuilder() = default;
31
32 template <typename... Args>
33 formats::yaml::Value Build(const Args&... args) {
34 static_assert(sizeof...(args) % 2 == 0, "Cannot build an object from an odd number of key-value arguments");
35 return DoBuild(args...);
36 }
37
38private:
39 formats::yaml::Value DoBuild();
40
41 template <typename FieldValue, typename... Tail>
42 formats::yaml::Value DoBuild(std::string_view key, const FieldValue& value, Tail&&... tail) {
43 Append(key, value);
44 return DoBuild(std::forward<Tail>(tail)...);
45 }
46
47 template <InlineValue FieldValue>
48 void Append(std::string_view key, const FieldValue& value) {
49 yaml_[std::string{key}] = value;
50 }
51
52 void Append(std::string_view key, const std::chrono::system_clock::time_point&);
53
54 formats::yaml::ValueBuilder yaml_{Type::kObject};
55};
56
57class InlineArrayBuilder {
58public:
59 InlineArrayBuilder() = default;
60
61 formats::yaml::Value Build();
62
63 template <typename... Elements>
64 formats::yaml::Value Build(const Elements&... elements) {
65 (Append(elements), ...);
66 return Build();
67 }
68
69private:
70 template <InlineValue Element>
71 void Append(const Element& value) {
72 yaml_.PushBack(value);
73 }
74
75 void Append(const std::chrono::system_clock::time_point&);
76
77 formats::yaml::ValueBuilder yaml_{Type::kArray};
78};
79
80} // namespace impl
81
82/// @ingroup userver_formats
83///
84/// Constructs an object Value from provided key-value pairs
85template <typename... Args>
86Value MakeObject(Args&&... args) {
87 return impl::InlineObjectBuilder().Build(std::forward<Args>(args)...);
88}
89
90/// @ingroup userver_formats
91///
92/// Constructs an array Value from provided element list
93template <typename... Args>
94Value MakeArray(Args&&... args) {
95 return impl::InlineArrayBuilder().Build(std::forward<Args>(args)...);
96}
97
98} // namespace formats::yaml
99
100USERVER_NAMESPACE_END