9 #ifndef DAQ_INTERNAL_PARSE_UTILS_HPP
10 #define DAQ_INTERNAL_PARSE_UTILS_HPP
13 #include <fmt/format.h>
14 #include <nlohmann/json.hpp>
18 using Json = nlohmann::json;
23 template <
class E,
class... Args>
25 return E((fmt::format(
"({}) {}", ptr.to_string(), fmt::format(std::forward<Args>(args)...)))
29 template <
class E,
char const*>
31 return E(fmt::format(
"({}) {}", ptr.to_string(), str).c_str());
36 return E(fmt::format(
"({}) {}", ptr.to_string(),
"mandatory value missing").c_str());
41 char const* expected_type,
42 char const* actual_type) {
43 return E(fmt::format(
"({}) {}",
45 fmt::format(
"must be a {}, but is {}", expected_type, actual_type))
51 char const* known_variants,
52 char const* actual_variant) {
54 fmt::format(
"({}) {}",
56 fmt::format(
"must be one of {}, but is '{}'", known_variants, actual_variant))
61 std::pair<Json const&, JsonPointer>
63 auto bc = breadcrumb / name;
64 if (!json.contains(name)) {
65 throw MakeValueMissingException<E>(breadcrumb);
67 return {json[name], bc};
70 template <
class E,
class BinaryFunction>
74 BinaryFunction
const& f) {
75 auto res = GetMember<E>(json, name, breadcrumb);
76 f(res.first, res.second);
80 template <
class E,
class T>
91 bool allow_empty =
true) {
92 if (!json.contains(name)) {
93 throw MakeValueMissingException<E>(breadcrumb / name);
95 auto const& value_json = json[name];
96 if (!value_json.is_string()) {
97 throw MakeWrongTypeException<E>(breadcrumb / name,
"string", value_json.type_name());
99 auto value = value_json.get<std::string>();
100 if (value.empty() && !allow_empty) {
101 throw MakeParseException<E>(breadcrumb / name,
"empty string is invalid");
112 if (!json.contains(name)) {
113 throw MakeValueMissingException<E>(breadcrumb / name);
115 auto const& value_json = json[name];
116 if (!value_json.is_number()) {
117 throw MakeWrongTypeException<E>(
118 breadcrumb / name,
"int or float", value_json.type_name());
120 auto value = value_json.get<
double>();
127 if (!json.is_object()) {
128 throw MakeWrongTypeException<E>(breadcrumb,
"object", json.type_name());
134 if (!json.is_array()) {
135 throw MakeWrongTypeException<E>(breadcrumb,
"array", json.type_name());
141 AssertIsArray<E>(json, breadcrumb);
142 std::vector<std::string> result;
144 for (
auto const& value_json : json) {
145 if (!value_json.is_string()) {
146 throw MakeWrongTypeException<E>(breadcrumb / index,
"string", value_json.type_name());
148 auto value = value_json.get<std::string>();
150 throw MakeParseException<E>(breadcrumb / index,
"empty string is invalid");
152 result.emplace_back(std::move(value));
Contains data structure for FITS keywords.
nlohmann::json_pointer< Json > JsonPointer
E MakeValueMissingException(JsonPointer const &ptr)
std::pair< Json const &, JsonPointer > GetMember(Json const &json, char const *name, JsonPointer const &breadcrumb)
std::vector< std::string > ParseArrayOfString(Json const &json, JsonPointer const &breadcrumb)
void AssertIsObject(Json const &json, JsonPointer const &breadcrumb)
E MakeUnknownVariantException(JsonPointer const &ptr, char const *known_variants, char const *actual_variant)
E MakeWrongTypeException(JsonPointer const &ptr, char const *expected_type, char const *actual_type)
E MakeParseException(JsonPointer const &ptr, Args &&... args)
void AssertIsArray(Json const &json, JsonPointer const &breadcrumb)
static double Get(Json const &json, char const *name, JsonPointer const &breadcrumb)
static std::string Get(Json const &json, char const *name, JsonPointer const &breadcrumb, bool allow_empty=true)
static T Get(Json const &json, char const *name, JsonPointer const &breadcrumb, bool allow_empty=true)