Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat json::Validate: return an error description #437

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions universal/include/userver/formats/json/validate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
/// @file userver/formats/json/validate.hpp
/// @brief json schema validator

#include <optional>

#include <userver/formats/json/value.hpp>
#include <userver/utils/fast_pimpl.hpp>

Expand All @@ -21,12 +23,12 @@ class Schema final {
static constexpr std::size_t kAlignment = 8;
utils::FastPimpl<Impl, kSize, kAlignment> pimpl_;

friend bool Validate(const formats::json::Value&,
const formats::json::Schema&);
friend std::optional<formats::json::Value> Validate(
const formats::json::Value& doc, const formats::json::Schema& schema);
};

bool Validate(const formats::json::Value& doc,
const formats::json::Schema& schema);
std::optional<formats::json::Value> Validate(
const formats::json::Value& doc, const formats::json::Schema& schema);

} // namespace formats::json

Expand Down
5 changes: 3 additions & 2 deletions universal/include/userver/formats/json/value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/// @file userver/formats/json/value.hpp
/// @brief @copybrief formats::json::Value

#include <optional>
#include <string_view>
#include <type_traits>

Expand Down Expand Up @@ -312,8 +313,8 @@ class Value final {
friend std::string ToPrettyString(const formats::json::Value& doc,
PrettyFormat format);
friend logging::LogHelper& operator<<(logging::LogHelper&, const Value&);
friend bool Validate(const formats::json::Value&,
const formats::json::Schema&);
friend std::optional<formats::json::Value> Validate(
const formats::json::Value&, const formats::json::Schema&);
};

template <typename T>
Expand Down
15 changes: 12 additions & 3 deletions universal/src/formats/json/validate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

#include <rapidjson/reader.h>
#include <rapidjson/schema.h>
#include <optional>

#include <formats/json/impl/accept.hpp>
#include <formats/json/impl/types_impl.hpp>
#include <userver/formats/json/impl/types.hpp>
#include <userver/formats/json/value.hpp>

Expand Down Expand Up @@ -31,10 +33,17 @@ Schema::Schema(const formats::json::Value& doc)

Schema::~Schema() = default;

bool Validate(const formats::json::Value& doc,
const formats::json::Schema& schema) {
std::optional<formats::json::Value> Validate(
const formats::json::Value& doc, const formats::json::Schema& schema) {
impl::SchemaValidator validator(schema.pimpl_->schemaDocument);
return AcceptNoRecursion(doc.GetNative(), validator);
if (!AcceptNoRecursion(doc.GetNative(), validator)) {
impl::Document json;
json.Swap(validator.GetError());
return formats::json::Value(
impl::VersionedValuePtr::Create(std::move(json)));
}

return {};
}

} // namespace formats::json
Expand Down
10 changes: 8 additions & 2 deletions universal/src/formats/json/validate_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,22 @@ constexpr std::string_view kInvalidInputJson{R"(
TEST(FormatsJsonValidate, ValidInput) {
auto schemaDocument = formats::json::FromString(kSchemaJson);
auto jsonDocument = formats::json::FromString(kValidInputJson);

formats::json::Schema schema(schemaDocument);
EXPECT_TRUE(formats::json::Validate(jsonDocument, schema));

auto validation_result = formats::json::Validate(jsonDocument, schema);
EXPECT_FALSE(validation_result.has_value());
}

TEST(FormatsJsonValidate, InvalidInput) {
auto schemaDocument = formats::json::FromString(kSchemaJson);
auto jsonDocument = formats::json::FromString(kInvalidInputJson);

formats::json::Schema schema(schemaDocument);
EXPECT_FALSE(formats::json::Validate(jsonDocument, schema));

auto validation_result = formats::json::Validate(jsonDocument, schema);
EXPECT_TRUE(validation_result.has_value());
EXPECT_TRUE(validation_result.value().HasMember("required"));
}

USERVER_NAMESPACE_END
Loading