47 error_out =
"transformation description must be an object";
52 if (!j.contains(
"transformation_type")) {
53 error_out =
"missing 'transformation_type'";
56 if (!j[
"transformation_type"].is_string() || j[
"transformation_type"].get<std::string>().empty()) {
57 error_out =
"'transformation_type' must be a non-empty string";
62 if (j.contains(
"parameters") && !j[
"parameters"].is_object()) {
63 error_out =
"'parameters' must be an object";
68 if (!j.contains(
"subgraph")) {
69 error_out =
"missing 'subgraph'";
72 const auto& subgraph = j[
"subgraph"];
73 if (!subgraph.is_object()) {
74 error_out =
"'subgraph' must be an object";
77 for (std::size_t i = 0; i < subgraph.size(); ++i) {
78 const auto key = std::to_string(i);
79 if (!subgraph.contains(key)) {
80 error_out =
"'subgraph' keys must be contiguous indices; missing '" + key +
"'";
83 const auto& node = subgraph[key];
84 if (!node.is_object()) {
85 error_out =
"'subgraph[" + key +
"]' must be an object";
88 if (!node.contains(
"element_id")) {
89 error_out =
"'subgraph[" + key +
"]' must have an 'element_id'";
92 const auto& element_id = node[
"element_id"];
93 const bool non_negative_integer = element_id.is_number_unsigned() ||
94 (element_id.is_number_integer() && element_id.get<
long long>() >= 0);
95 if (!non_negative_integer) {
96 error_out =
"'subgraph[" + key +
"]' must have a non-negative integer 'element_id'";
99 if (!node.contains(
"type") || !node[
"type"].is_string()) {
100 error_out =
"'subgraph[" + key +
"]' must have a string 'type'";
106 for (
auto it = j.begin(); it != j.end(); ++it) {
107 if (it.key() !=
"transformation_type" && it.key() !=
"subgraph" && it.key() !=
"parameters") {
108 error_out =
"unexpected top-level key '" + it.key() +
"'";