ifw-daq 3.1.0
IFW Data Acquisition modules
Loading...
Searching...
No Matches
internalParseUtils.hpp
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup daq_libjson
4 * @copyright
5 * (c) Copyright ESO 2022
6 * All Rights Reserved
7 * ESO (eso.org) is an Intergovernmental Organisation, and therefore special legal conditions apply.
8 */
9#ifndef DAQ_INTERNAL_PARSE_UTILS_HPP
10#define DAQ_INTERNAL_PARSE_UTILS_HPP
11#include <string>
12
13#include <fmt/format.h>
14#include <nlohmann/json.hpp>
15
16#include <daq/fits/json.hpp>
17
18using Json = nlohmann::json;
19using JsonPointer = nlohmann::json_pointer<Json>;
20
21namespace daq {
22
23template <class E, class... Args>
24E MakeParseException(JsonPointer const& ptr, Args&&... args) {
25 return E((fmt::format("({}) {}", ptr.to_string(), fmt::format(std::forward<Args>(args)...)))
26 .c_str());
27}
28
29template <class E, char const*>
30E MakeParseException(JsonPointer const& ptr, char const* str) {
31 return E(fmt::format("({}) {}", ptr.to_string(), str).c_str());
32}
33
34template <class E>
36 return E(fmt::format("({}) {}", ptr.to_string(), "mandatory value missing").c_str());
37}
38
39template <class E>
41 char const* expected_type,
42 char const* actual_type) {
43 return E(fmt::format("({}) {}",
44 ptr.to_string(),
45 fmt::format("must be a {}, but is {}", expected_type, actual_type))
46 .c_str());
47}
48
49template <class E>
51 char const* known_variants,
52 char const* actual_variant) {
53 return E(
54 fmt::format("({}) {}",
55 ptr.to_string(),
56 fmt::format("must be one of {}, but is '{}'", known_variants, actual_variant))
57 .c_str());
58}
59
60template <class E>
61std::pair<Json const&, JsonPointer>
62GetMember(Json const& json, char const* name, JsonPointer const& breadcrumb) {
63 auto bc = breadcrumb / name;
64 if (!json.contains(name)) {
65 throw MakeValueMissingException<E>(bc);
66 }
67 return {json[name], bc};
68}
69
70template <class E, class BinaryFunction>
71std::pair<Json const&, JsonPointer> GetMember(Json const& json,
72 char const* name,
73 JsonPointer const& breadcrumb,
74 BinaryFunction const& f) {
75 auto res = GetMember<E>(json, name, breadcrumb);
76 f(res.first, res.second);
77 return res;
78}
79
80template <class E, class T>
81struct JsonObject {
82 static T
83 Get(Json const& json, char const* name, JsonPointer const& breadcrumb, bool allow_empty = true);
84};
85
86template <class E>
87struct JsonObject<E, std::string> {
88 static std::string Get(Json const& json,
89 char const* name,
90 JsonPointer const& breadcrumb,
91 bool allow_empty = true) {
92 if (!json.contains(name)) {
93 throw MakeValueMissingException<E>(breadcrumb / name);
94 }
95 auto const& value_json = json[name];
96 if (!value_json.is_string()) {
97 throw MakeWrongTypeException<E>(breadcrumb / name, "string", value_json.type_name());
98 }
99 auto value = value_json.get<std::string>();
100 if (value.empty() && !allow_empty) {
101 throw MakeParseException<E>(breadcrumb / name, "empty string is invalid");
102 }
103 return value;
104 }
105};
106
107template <class E>
108struct JsonObject<E, double> {
109 static double Get(Json const& json,
110 char const* name,
111 JsonPointer const& breadcrumb) {
112 if (!json.contains(name)) {
113 throw MakeValueMissingException<E>(breadcrumb / name);
114 }
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());
119 }
120 auto value = value_json.get<double>();
121 return value;
122 }
123};
124
125template <class E>
126struct JsonObject<E, bool> {
127 static double Get(Json const& json,
128 char const* name,
129 JsonPointer const& breadcrumb) {
130 if (!json.contains(name)) {
131 throw MakeValueMissingException<E>(breadcrumb / name);
132 }
133 auto const& value_json = json[name];
134 if (!value_json.is_boolean()) {
135 throw MakeWrongTypeException<E>(
136 breadcrumb / name, "boolean", value_json.type_name());
137 }
138 auto value = value_json.get<bool>();
139 return value;
140 }
141};
142
143template <class E>
144void AssertIsObject(Json const& json, JsonPointer const& breadcrumb) {
145 if (!json.is_object()) {
146 throw MakeWrongTypeException<E>(breadcrumb, "object", json.type_name());
147 }
148}
149
150template <class E>
151void AssertIsArray(Json const& json, JsonPointer const& breadcrumb) {
152 if (!json.is_array()) {
153 throw MakeWrongTypeException<E>(breadcrumb, "array", json.type_name());
154 }
155}
156
157template <class E>
158std::vector<std::string> ParseArrayOfString(Json const& json, JsonPointer const& breadcrumb) {
159 AssertIsArray<E>(json, breadcrumb);
160 std::vector<std::string> result;
161 auto index = 0u;
162 for (auto const& value_json : json) {
163 if (!value_json.is_string()) {
164 throw MakeWrongTypeException<E>(breadcrumb / index, "string", value_json.type_name());
165 }
166 auto value = value_json.get<std::string>();
167 if (value.empty()) {
168 throw MakeParseException<E>(breadcrumb / index, "empty string is invalid");
169 }
170 result.emplace_back(std::move(value));
171 index++;
172 }
173 return result;
174}
175} // namespace daq
176#endif // DAQ_INTERNAL_PARSE_UTILS_HPP
Contains data structure for FITS keywords.
nlohmann::json_pointer< Json > JsonPointer
Definition: json.cpp:19
nlohmann::json Json
Definition: json.cpp:18
E MakeValueMissingException(JsonPointer const &ptr)
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)
std::pair< Json const &, JsonPointer > GetMember(Json const &json, char const *name, JsonPointer const &breadcrumb)
E MakeParseException(JsonPointer const &ptr, Args &&... args)
void AssertIsArray(Json const &json, JsonPointer const &breadcrumb)
std::vector< std::string > ParseArrayOfString(Json const &json, JsonPointer const &breadcrumb)
static double Get(Json const &json, char const *name, 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)