-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathenvironment.h
More file actions
156 lines (125 loc) · 4.31 KB
/
environment.h
File metadata and controls
156 lines (125 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#pragma once
// This component provides a registry of all environment variables that can be
// used to configure this library.
//
// Each `enum Variable` denotes an environment variable. The enum value names
// are the same as the names of the environment variables.
//
// `name` returns the name of a specified `Variable`.
//
// `lookup` retrieves the value of `Variable` in the environment.
#include <datadog/environment_registry.h>
#include <datadog/expected.h>
#include <datadog/optional.h>
#include <datadog/string_view.h>
#include <cstdint>
#include <cstdlib>
namespace datadog {
namespace tracing {
namespace environment {
enum class VariableType {
STRING,
BOOLEAN,
INT,
DECIMAL,
ARRAY,
MAP,
};
struct VariableSpec {
StringView name;
VariableType type;
};
#define VARIABLE_ENUM_VALUE(DATA, NAME, TYPE, DEFAULT_VALUE) NAME,
enum Variable { DD_ENVIRONMENT_VARIABLES(VARIABLE_ENUM_VALUE, ~) };
// Quoting a macro argument requires this two-step.
#define QUOTED_IMPL(ARG) #ARG
#define QUOTED(ARG) QUOTED_IMPL(ARG)
#define VARIABLE_SPEC_WITH_COMMA(DATA, NAME, TYPE, DEFAULT_VALUE) \
VariableSpec{StringView{QUOTED(NAME)}, VariableType::TYPE},
inline const VariableSpec variable_specs[] = {
DD_ENVIRONMENT_VARIABLES(VARIABLE_SPEC_WITH_COMMA, ~)};
template <VariableType type>
struct LookupResultByType;
template <>
struct LookupResultByType<VariableType::STRING> {
using type = Optional<StringView>;
};
template <>
struct LookupResultByType<VariableType::BOOLEAN> {
using type = Optional<bool>;
};
template <>
struct LookupResultByType<VariableType::INT> {
using type = Expected<Optional<std::uint64_t>>;
};
template <>
struct LookupResultByType<VariableType::DECIMAL> {
using type = Expected<Optional<double>>;
};
template <>
struct LookupResultByType<VariableType::ARRAY> {
using type = Optional<StringView>;
};
template <>
struct LookupResultByType<VariableType::MAP> {
using type = Optional<StringView>;
};
template <Variable variable>
struct VariableTraits;
#define VARIABLE_TRAITS_VALUE(DATA, NAME, TYPE, DEFAULT_VALUE) \
template <> \
struct VariableTraits<NAME> { \
static constexpr VariableType variable_type = VariableType::TYPE; \
static constexpr const char *name() { return QUOTED(NAME); } \
using lookup_result = typename LookupResultByType<variable_type>::type; \
};
DD_ENVIRONMENT_VARIABLES(VARIABLE_TRAITS_VALUE, ~)
template <Variable variable>
using LookupResult = typename VariableTraits<variable>::lookup_result;
namespace detail {
template <VariableType>
inline constexpr bool unsupported_variable_type_v = false;
template <Variable variable>
Optional<StringView> lookup_raw() {
const char *value = std::getenv(VariableTraits<variable>::name());
if (!value) {
return nullopt;
}
return StringView{value};
}
Optional<bool> lookup_bool_from_raw(Optional<StringView> value);
Expected<Optional<std::uint64_t>> lookup_uint64_from_raw(
Optional<StringView> value);
Expected<Optional<double>> lookup_double_from_raw(Optional<StringView> value);
} // namespace detail
template <Variable variable>
LookupResult<variable> lookup() {
constexpr VariableType type = VariableTraits<variable>::variable_type;
const auto raw = detail::lookup_raw<variable>();
if constexpr (type == VariableType::STRING || type == VariableType::ARRAY ||
type == VariableType::MAP) {
return raw;
} else if constexpr (type == VariableType::BOOLEAN) {
return detail::lookup_bool_from_raw(raw);
} else if constexpr (type == VariableType::INT) {
return detail::lookup_uint64_from_raw(raw);
} else if constexpr (type == VariableType::DECIMAL) {
return detail::lookup_double_from_raw(raw);
} else {
static_assert(detail::unsupported_variable_type_v<type>,
"Unsupported environment variable type");
}
}
#undef VARIABLE_SPEC_WITH_COMMA
#undef VARIABLE_TRAITS_VALUE
#undef QUOTED
#undef QUOTED_IMPL
#undef VARIABLE_ENUM_VALUE
// Return the metadata for the specified environment `variable`.
const VariableSpec &spec(Variable variable);
// Return the name of the specified environment `variable`.
StringView name(Variable variable);
std::string to_json();
} // namespace environment
} // namespace tracing
} // namespace datadog