userver
C++ Async Framework
Toggle main menu visibility
Documentation
API Groups
Namespaces
Reference
Class List
Class Index
File List
Macros
All
e
i
l
r
t
u
Functions
Macros
e
i
l
r
t
u
Examples
•
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Modules
Pages
Concepts
Loading...
Searching...
No Matches
yaml_config.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/yaml_config/yaml_config.hpp
4
/// @brief @copybrief yaml_config::YamlConfig
5
6
#
include
<
chrono
>
7
#
include
<
cstdint
>
8
#
include
<
optional
>
9
#
include
<
string
>
10
#
include
<
string_view
>
11
12
#
include
<
userver
/
formats
/
json_fwd
.
hpp
>
13
#
include
<
userver
/
formats
/
parse
/
common
.
hpp
>
14
#
include
<
userver
/
formats
/
parse
/
common_containers
.
hpp
>
15
#
include
<
userver
/
formats
/
yaml
/
value
.
hpp
>
16
17
#
include
<
userver
/
yaml_config
/
iterator
.
hpp
>
18
19
USERVER_NAMESPACE_BEGIN
20
21
/// Utilities to work with static YAML config
22
namespace
yaml_config
{
23
24
using
Exception =
formats
::
yaml
::
Exception
;
25
using
ParseException =
formats
::
yaml
::
ParseException
;
26
27
/// @ingroup userver_formats userver_universal
28
///
29
/// @brief Datatype that represents YAML with substituted variables
30
///
31
/// If YAML has value that starts with an `$`, then such value is treated as
32
/// a variable from `config_vars`. For example if `config_vars` contains
33
/// `variable: 42` and the YAML is following:
34
/// @snippet universal/src/yaml_config/yaml_config_test.cpp sample vars
35
/// Then the result of `yaml["some_element"]["some"].As<int>()` is `42`.
36
///
37
/// If YAML key ends on `#env` and the mode is YamlConfig::Mode::kEnvAllowed
38
/// or YamlConfig::Mode::kEnvAndFileAllowed,
39
/// then the value of the key is searched in
40
/// environment variables of the process and returned as a value. For example:
41
/// @snippet universal/src/yaml_config/yaml_config_test.cpp sample env
42
///
43
/// If YAML key ends on `#file` and the mode is
44
/// YamlConfig::Mode::kEnvAndFileAllowed, then the value of the key is the
45
/// content of specified YAML parsed file. For example:
46
/// @snippet universal/src/yaml_config/yaml_config_test.cpp sample read_file
47
///
48
/// If YAML key ends on `#fallback`, then the value of the key is used as a
49
/// fallback for environment, file and `$` variables. For example for the
50
/// following YAML with YamlConfig::Mode::kEnvAndFileAllowed:
51
/// @snippet universal/src/yaml_config/yaml_config_test.cpp sample multiple
52
/// The result of `yaml["some_element"]["some"].As<int>()` is the value of
53
/// `variable` from `config_vars` if it exists; otherwise the value is the
54
/// contents of the environment variable `SOME_ENV_VARIABLE` if it exists;
55
/// otherwise the value is the content of the file with name `file.yaml`;
56
/// otherwise the value is `100500`, from the fallback.
57
///
58
/// Another example:
59
/// @snippet universal/src/yaml_config/yaml_config_test.cpp sample env fallback
60
/// With YamlConfig::Mode::kEnvAllowed the result of
61
/// `yaml["some_element"]["some"].As<int>()` is the value of `ENV_NAME`
62
/// environment variable if it exists; otherwise it is `5`.
63
///
64
/// @note `#env`, `#file` and `#fallback` also work for keys inside
65
/// `config_vars`.
66
///
67
/// @warning YamlConfig::Mode::kEnvAllowed or
68
/// YamlConfig::Mode::kEnvAndFileAllowed should be used only on configs that
69
/// come from trusted environments. Otherwise, an attacker could create a
70
/// config and read any of your environment variables of files, including
71
/// variables that contain passwords and other sensitive data.
72
class
YamlConfig
{
73
public
:
74
struct
IterTraits
{
75
using
value_type =
YamlConfig
;
76
using
reference =
const
YamlConfig
&;
77
using
pointer =
const
YamlConfig
*;
78
};
74
struct
IterTraits
{
…
};
79
struct
DefaultConstructed
{};
80
81
enum
class
Mode
{
82
kSecure,
/// < secure mode, without reading environment variables or files
83
kEnvAllowed
,
/// < allows reading of environment variables
84
kEnvAndFileAllowed
,
/// < allows reading of environment variables and
85
/// files
86
};
81
enum
class
Mode
{
…
};
87
88
using
const_iterator = Iterator<
IterTraits
>;
89
using
Exception =
yaml_config
::Exception;
90
using
ParseException =
yaml_config
::ParseException;
91
92
YamlConfig() =
default
;
93
94
/// YamlConfig = config + config_vars
95
YamlConfig
(
formats
::
yaml
::Value yaml,
formats
::
yaml
::Value config_vars,
Mode
mode =
Mode
::kSecure);
96
97
/// @brief Access member by key for read.
98
/// @throw TypeMismatchException if value is not missing and is not object.
99
YamlConfig
operator
[](std::string_view key)
const
;
100
101
/// @brief Access member by index for read.
102
/// @throw TypeMismatchException if value is not missing and is not array.
103
YamlConfig
operator
[](size_t index)
const
;
104
105
/// @brief Returns array size or object members count.
106
/// @throw TypeMismatchException if not array or object value.
107
std::size_t
GetSize
()
const
;
108
109
/// @brief Returns true if *this holds nothing. When `IsMissing()` returns
110
/// `true` any attempt to get the actual value or iterate over *this will
111
/// throw MemberMissingException.
112
bool
IsMissing
()
const
noexcept
;
113
114
/// @brief Returns true if *this holds 'null'.
115
bool
IsNull
()
const
noexcept
;
116
117
/// @brief Returns true if *this is convertible to bool.
118
bool
IsBool
()
const
noexcept
;
119
120
/// @brief Returns true if *this is convertible to int.
121
bool
IsInt
()
const
noexcept
;
122
123
/// @brief Returns true if *this is convertible to int64_t.
124
bool
IsInt64
()
const
noexcept
;
125
126
/// @brief Returns true if *this is convertible to uint64_t.
127
bool
IsUInt64
()
const
noexcept
;
128
129
/// @brief Returns true if *this is convertible to double.
130
bool
IsDouble
()
const
noexcept
;
131
132
/// @brief Returns true if *this is convertible to std::string.
133
bool
IsString
()
const
noexcept
;
134
135
/// @brief Returns true if *this is an array (Type::kArray).
136
bool
IsArray
()
const
noexcept
;
137
138
/// @brief Returns true if *this is a map (Type::kObject).
139
bool
IsObject
()
const
noexcept
;
140
141
/// @throw MemberMissingException if `this->IsMissing()`.
142
void
CheckNotMissing
()
const
;
143
144
/// @throw MemberMissingException if `*this` is not an array.
145
void
CheckArray
()
const
;
146
147
/// @throw MemberMissingException if `*this` is not an array or Null.
148
void
CheckArrayOrNull
()
const
;
149
150
/// @throw TypeMismatchException if `*this` is not a map or Null.
151
void
CheckObjectOrNull
()
const
;
152
153
/// @throw TypeMismatchException if `*this` is not a map.
154
void
CheckObject
()
const
;
155
156
/// @throw TypeMismatchException if `*this` is not convertible to std::string.
157
void
CheckString
()
const
;
158
159
/// @throw TypeMismatchException if `*this` is not a map, array or Null.
160
void
CheckObjectOrArrayOrNull
()
const
;
161
162
/// @brief Returns value of *this converted to T.
163
/// @throw Anything derived from std::exception.
164
template
<
typename
T>
165
auto
As
()
const
;
166
167
/// @brief Returns value of *this converted to T or T(args) if
168
/// this->IsMissing().
169
/// @throw Anything derived from std::exception.
170
template
<
typename
T,
typename
First,
typename
... Rest>
171
auto
As
(First&& default_arg, Rest&&... more_default_args)
const
;
172
173
/// @brief Returns value of *this converted to T or T() if this->IsMissing().
174
/// @throw Anything derived from std::exception.
175
/// @note Use as `value.As<T>({})`
176
template
<
typename
T>
177
auto
As
(
DefaultConstructed
)
const
;
178
179
/// @brief Returns true if *this holds a `key`.
180
/// @throw Nothing.
181
bool
HasMember
(std::string_view key)
const
;
182
183
/// @brief Returns full path to this value.
184
std::string
GetPath
()
const
;
185
186
/// @brief Returns an iterator to the beginning of the held array or map.
187
/// @throw TypeMismatchException is the value of *this is not a map, array
188
/// or Null.
189
const_iterator
begin
()
const
;
190
191
/// @brief Returns an iterator to the end of the held array or map.
192
/// @throw TypeMismatchException is the value of *this is not a map, array
193
/// or Null.
194
const_iterator
end
()
const
;
195
196
/// @brief Get the plain Yaml without substitutions. It may contain raw references.
197
/// @deprecated Either use the current `YamlConfig` as a formats value, or use `.As<formats::json::Value>()`
198
/// to get the correct treatment for `$vars`, `#fallback`, `#env` and `#file`.
199
formats
::
yaml
::Value
GetRawYamlWithoutConfigVars
()
const
;
200
201
private
:
202
formats
::
yaml
::Value yaml_;
203
formats
::
yaml
::Value config_vars_;
204
Mode
mode_{
Mode
::kSecure};
205
206
friend
bool
Parse(
const
YamlConfig
& value,
formats
::
parse
::
To
<
bool
>);
207
friend
int64_t Parse(
const
YamlConfig
& value,
formats
::
parse
::
To
<int64_t>);
208
friend
uint64_t Parse(
const
YamlConfig
& value,
formats
::
parse
::
To
<uint64_t>);
209
friend
double
Parse(
const
YamlConfig
& value,
formats
::
parse
::
To
<
double
>);
210
friend
std::string Parse(
const
YamlConfig
& value,
formats
::
parse
::
To
<std::string>);
211
friend
formats
::
yaml
::Value
Parse
(
const
YamlConfig
& value,
formats
::
parse
::
To
<
formats
::
yaml
::Value>);
212
};
72
class
YamlConfig
{
…
};
213
214
using
Value =
YamlConfig
;
215
216
template
<
typename
T>
217
auto
YamlConfig
::
As
()
const
{
218
static_assert
(
219
formats
::
common
::impl::kHasParse<
YamlConfig
, T>,
220
"There is no `Parse(const yaml_config::YamlConfig&, "
221
"formats::parse::To<T>)`"
222
"in namespace of `T` or `formats::parse`. "
223
"Probably you forgot to include the "
224
"<userver/formats/parse/common_containers.hpp> or you "
225
"have not provided a `Parse` function overload."
226
);
227
228
return
Parse(*
this
,
formats
::
parse
::
To
<T>{});
229
}
217
auto
YamlConfig
::
As
()
const
{
…
}
230
231
bool
Parse(
const
YamlConfig
& value,
formats
::
parse
::
To
<
bool
>);
232
233
int64_t Parse(
const
YamlConfig
& value,
formats
::
parse
::
To
<int64_t>);
234
235
uint64_t Parse(
const
YamlConfig
& value,
formats
::
parse
::
To
<uint64_t>);
236
237
double
Parse(
const
YamlConfig
& value,
formats
::
parse
::
To
<
double
>);
238
239
std::string Parse(
const
YamlConfig
& value,
formats
::
parse
::
To
<std::string>);
240
241
template
<
typename
T,
typename
First,
typename
... Rest>
242
auto
YamlConfig
::
As
(First&& default_arg, Rest&&... more_default_args)
const
{
243
if
(
IsMissing
(
)
) {
244
// intended raw ctor call, sometimes casts
245
// NOLINTNEXTLINE(google-readability-casting)
246
return
decltype
(As<T>())(std::forward<First>(default_arg), std::forward<Rest>(more_default_args)...);
247
}
248
return
As<T>();
249
}
242
auto
YamlConfig
::
As
(First&& default_arg, Rest&&... more_default_args)
const
{
…
}
250
251
template
<
typename
T>
252
auto
YamlConfig
::
As
(
YamlConfig
::
DefaultConstructed
)
const
{
253
return
IsMissing
(
)
?
decltype
(As<T>())() : As<T>();
254
}
252
auto
YamlConfig
::
As
(
YamlConfig
::
DefaultConstructed
)
const
{
…
}
255
256
/// @brief Wrapper for handy python-like iteration over a map
257
///
258
/// @code
259
/// for (const auto& [name, value]: Items(map)) ...
260
/// @endcode
261
using
formats
::
common
::Items;
262
263
/// @brief Parses duration from string, understands suffixes: ms, s, m, h, d
264
/// @throws On invalid type, invalid string format, and if the duration is not a
265
/// whole amount of seconds
266
std::chrono::seconds
Parse
(
const
YamlConfig
& value,
formats
::
parse
::
To
<std::chrono::seconds>);
267
268
/// @brief Parses duration from string, understands suffixes: ms, s, m, h, d
269
/// @throws On invalid type and invalid string format
270
std::chrono::milliseconds
Parse
(
const
YamlConfig
& value,
formats
::
parse
::
To
<std::chrono::milliseconds>);
271
272
/// @brief Converts YAML to JSON
273
/// @throws yaml_config::YamlConfig::Exception if `value.IsMissing()`
274
formats
::
json
::Value
Parse
(
const
YamlConfig
& value,
formats
::
parse
::
To
<
formats
::
json
::Value>);
275
276
/// @brief Converts YAML to YAML. Returns self
277
inline
YamlConfig
Parse
(
const
YamlConfig
& value,
formats
::
parse
::
To
<
YamlConfig
>) {
return
value; }
278
279
/// @brief Flattens a YamlConfig, applying all of its special syntax
280
/// @throws yaml_config::YamlConfig::Exception if `value.IsMissing()`
281
formats
::
yaml
::Value
Parse
(
const
YamlConfig
& value,
formats
::
parse
::
To
<
formats
::
yaml
::Value>);
282
283
}
// namespace yaml_config
284
285
USERVER_NAMESPACE_END
userver
yaml_config
yaml_config.hpp
Generated on Fri Apr 11 2025 14:16:01 for userver by
Doxygen
1.13.2