Exemplo n.º 1
0
 AllOfValidator(SchemaValidatorContext& context, const dynamic& schema) {
   if (schema.isArray()) {
     for (const auto& item : schema) {
       validators_.emplace_back(SchemaValidator::make(context, item));
     }
   }
 }
Exemplo n.º 2
0
 Optional<SchemaError> validate(ValidationContext& vc,
                                const dynamic& value) const override {
   if (!value.isArray()) {
     return none;
   }
   if (itemsValidator_) {
     for (const auto& v : value) {
       if (auto se = vc.validate(itemsValidator_.get(), v)) {
         return se;
       }
     }
     return none;
   }
   size_t pos = 0;
   for (; pos < value.size() && pos < itemsValidators_.size(); ++pos) {
     if (auto se = vc.validate(itemsValidators_[pos].get(), value[pos])) {
       return se;
     }
   }
   if (!allowAdditionalItems_ && pos < value.size()) {
     return makeError("no more additional items", value);
   }
   if (additionalItemsValidator_) {
     for (; pos < value.size(); ++pos) {
       if (auto se =
               vc.validate(additionalItemsValidator_.get(), value[pos])) {
         return se;
       }
     }
   }
   return none;
 }
Exemplo n.º 3
0
 explicit RequiredValidator(const dynamic& schema) {
   if (schema.isArray()) {
     for (const auto& item : schema) {
       if (item.isString()) {
         properties_.emplace_back(item.getString());
       }
     }
   }
 }
Exemplo n.º 4
0
 explicit TypeValidator(const dynamic& schema) {
   if (schema.isString()) {
     addType(schema.stringPiece());
   } else if (schema.isArray()) {
     for (const auto& item : schema) {
       if (item.isString()) {
         addType(item.stringPiece());
       }
     }
   }
 }
Exemplo n.º 5
0
 Optional<SchemaError> validate(ValidationContext&,
                                const dynamic& value) const override {
   if (!unique_ || !value.isArray()) {
     return none;
   }
   for (const auto& i : value) {
     for (const auto& j : value) {
       if (&i != &j && i == j) {
         return makeError("unique items in array", value);
       }
     }
   }
   return none;
 }
Exemplo n.º 6
0
JobBackoffSettings::JobBackoffSettings(const dynamic& d) : repeat_(false) {
  if (!d.isArray()) {
    throw BistroException("Expected array; got ", folly::toJson(d));
  }
  if (d.empty()) {
    throw BistroException("Backoff setting is empty");
  }
  for (const auto& item : d) {
    if (item.isInt()) {
      int val = item.asInt();
      if (val <= 0) {
        throw BistroException("Backoff times must be positive: ", val);
      }
      if (!values_.empty()) {
        if (values_.back() == val) {
          throw BistroException("Duplicate backoff time: ", val);
        }
        if (values_.back() > val) {
          throw BistroException("Backoff times must be in increasing order");
        }
      }
      values_.push_back(val);
    } else if (item.isString()) {
      const auto& s = item.asString();
      if (s == "repeat") {
        if (values_.empty()) {
          throw BistroException("No backoff interval given before 'repeat'");
        }
        repeat_ = true;
      } else if  (s != "fail") {
        throw BistroException("Unknown string in backoff settings: ", s);
      }
      break;
    } else {
      throw BistroException("Invalid backoff value: ", folly::toJson(item));
    }
  }
}
Exemplo n.º 7
0
// static
Expected<json_patch, json_patch::parse_error> json_patch::try_parse(
    dynamic const& obj) noexcept {
  using err_code = parse_error_code;

  json_patch patch;
  if (!obj.isArray()) {
    return makeUnexpected(parse_error{err_code::invalid_shape, &obj});
  }
  for (auto const& elem : obj) {
    if (!elem.isObject()) {
      return makeUnexpected(parse_error{err_code::invalid_shape, &elem});
    }
    auto const* op_ptr = elem.get_ptr(kOpTag);
    if (!op_ptr) {
      return makeUnexpected(parse_error{err_code::missing_op, &elem});
    }
    if (!op_ptr->isString()) {
      return makeUnexpected(parse_error{err_code::malformed_op, &elem});
    }
    auto const op_str = op_ptr->asString();
    patch_operation op;

    // extract 'from' attribute
    {
      auto const* from_ptr = elem.get_ptr(kFromTag);
      if (from_ptr) {
        if (!from_ptr->isString()) {
          return makeUnexpected(parse_error{err_code::invalid_shape, &elem});
        }
        auto json_ptr = json_pointer::try_parse(from_ptr->asString());
        if (!json_ptr.hasValue()) {
          return makeUnexpected(
              parse_error{err_code::malformed_from_attr, &elem});
        }
        op.from = json_ptr.value();
      }
    }

    // extract 'path' attribute
    {
      auto const* path_ptr = elem.get_ptr(kPathTag);
      if (!path_ptr) {
        return makeUnexpected(parse_error{err_code::missing_path_attr, &elem});
      }
      if (!path_ptr->isString()) {
        return makeUnexpected(
            parse_error{err_code::malformed_path_attr, &elem});
      }
      auto const json_ptr = json_pointer::try_parse(path_ptr->asString());
      if (!json_ptr.hasValue()) {
        return makeUnexpected(
            parse_error{err_code::malformed_path_attr, &elem});
      }
      op.path = json_ptr.value();
    }

    // extract 'value' attribute
    {
      auto const* val_ptr = elem.get_ptr(kValueTag);
      if (val_ptr) {
        op.value = *val_ptr;
      }
    }

    // check mandatory attributes - different per operation
    // NOTE: per RFC, the surplus attributes (e.g. 'from' with 'add')
    // should be simply ignored

    using op_code = patch_operation_code;

    if (op_str == kOperationTest) {
      if (!op.value) {
        return makeUnexpected(parse_error{err_code::missing_value_attr, &elem});
      }
      op.op_code = op_code::test;
    } else if (op_str == kOperationRemove) {
      op.op_code = op_code::remove;
    } else if (op_str == kOperationAdd) {
      if (!op.value) {
        return makeUnexpected(parse_error{err_code::missing_value_attr, &elem});
      }
      op.op_code = op_code::add;
    } else if (op_str == kOperationReplace) {
      if (!op.value) {
        return makeUnexpected(parse_error{err_code::missing_value_attr, &elem});
      }
      op.op_code = op_code::replace;
    } else if (op_str == kOperationMove) {
      if (!op.from) {
        return makeUnexpected(parse_error{err_code::missing_from_attr, &elem});
      }
      // is from a proper prefix to path?
      if (op.from->is_prefix_of(op.path)) {
        return makeUnexpected(
            parse_error{err_code::overlapping_pointers, &elem});
      }
      op.op_code = op_code::move;
    } else if (op_str == kOperationCopy) {
      if (!op.from) {
        return makeUnexpected(parse_error{err_code::missing_from_attr, &elem});
      }
      op.op_code = op_code::copy;
    }

    if (op.op_code != op_code::invalid) {
      patch.ops_.emplace_back(std::move(op));
    } else {
      return makeUnexpected(parse_error{err_code::unknown_op, &elem});
    }
  }
  return patch;
}