9 #include <fmt/format.h>
15 using Json = nlohmann::json;
21 AssertIsObject<DpSpecError>(json, breadcrumb);
24 if (json.contains(
"source")) {
27 if (json.contains(
"filePrefix")) {
35 AssertIsObject<DpSpecError>(json, breadcrumb);
37 if (type ==
"fitsKeywords") {
39 }
else if (type ==
"fitsFile") {
42 throw MakeUnknownVariantException<DpSpecError>(
43 breadcrumb /
"type",
"'fitsKeywords' or 'fitsFile'", type.c_str());
50 AssertIsObject<DpSpecError>(json, breadcrumb);
54 if (!json.contains(
"target")) {
55 throw MakeValueMissingException<DpSpecError>(breadcrumb /
"target");
57 spec.target =
ParseTarget(json[
"target"], breadcrumb /
"target");
59 if (json.contains(
"sources")) {
60 auto const& json_sources = json[
"sources"];
61 if (!json_sources.is_array()) {
62 throw MakeWrongTypeException<DpSpecError>(
63 breadcrumb /
"sources",
"array", json_sources.type_name());
67 for (
auto const& json_source : json_sources) {
69 spec.sources.emplace_back(
ParseSource(json_source, breadcrumb /
"sources" / index));
74 if (!spec.target.source && spec.sources.empty()) {
75 throw MakeParseException<DpSpecError>(
76 breadcrumb /
"sources",
77 "At least one source must be provided if '/target/source' is not used");
83 std::throw_with_nested(
DpSpecError(
"Schema error"));
85 std::throw_with_nested(
DpSpecError(
"Unknown parsing error"));
93 auto start_pos = location_str.find(
'@');
94 if (start_pos == std::string::npos) {
98 if (start_pos > location_str.size()) {
99 throw std::invalid_argument(
100 fmt::format(
"Invalid format of location string: '{}'", location_str));
106 auto pos = location_str.find(
':', start_pos);
107 if (pos != std::string::npos) {
109 location.
host = location_str.substr(start_pos, pos - start_pos);
110 location.
path = location_str.substr(pos + 1, std::string::npos);
112 location.
path = location_str.substr(start_pos);
114 if (location.
path.empty()) {
115 throw std::invalid_argument(
116 fmt::format(
"Invalid format of location string: '{}'", location_str));
125 return (
host + std::string(
":") +
path.native());
136 if (s.
source.has_value()) {
143 std::visit([&](
auto const& val) { j =
Json(val); }, s);
Contains data structure for FITS keywords.
nlohmann::json_pointer< Json > JsonPointer
Location ParseSourceLocation(std::string const &location_str)
Parse location string from DpSpec into component parts.
DpSpec ParseDpSpec(Json const &json)
Parse JSON to construct the DpSpec structure.
std::optional< FitsFileSource > source
std::vector< SourceTypes > sources
std::variant< FitsKeywordsSource, FitsFileSource > SourceTypes
DpSpec::SourceTypes ParseSource(Json const &json, JsonPointer const &breadcrumb)
std::string file_prefix
Optioal user chosen file prefix to make it easier to identify the produced file.
FitsFileSource ParseFitsFileSource(Json const &json, JsonPointer const &breadcrumb)
FitsKeywordsSource ParseFitsKeywordsSource(Json const &json, JsonPointer const &breadcrumb)
void to_json(nlohmann::json &out, KeywordFilter const &s)
DpSpec::Target ParseTarget(Json const &json, JsonPointer const &breadcrumb)
Close representation of the JSON structure but with stronger types.
static T Get(Json const &json, char const *name, JsonPointer const &breadcrumb, bool allow_empty=true)
Describes parsed location string into its components "host" and "path".
std::filesystem::path path
std::string RsyncPath() const