diff options
author | jansenin <jansenin@yandex-team.com> | 2023-09-13 11:58:19 +0300 |
---|---|---|
committer | jansenin <jansenin@yandex-team.com> | 2023-09-13 12:21:09 +0300 |
commit | 64a5ddcdef53b30c561b1e01d776993a6ac4e5d3 (patch) | |
tree | db757ecc4ade2b2e1e71be2b99e2e90382d6a550 | |
parent | 47e6d33389b288c5ebf87cbc1b896754d63fe2ef (diff) | |
download | ydb-64a5ddcdef53b30c561b1e01d776993a6ac4e5d3.tar.gz |
exceptions, fail and assert, style things
fix erros and some style things
change context pointer to context reference
move to TNodeWrapperCommonOps more things
put fyaml errors to validation result
throw TCheckErrors from chekers instead of yexceptions
change T<Type>CehckContext in nodewrappers to TCheckContext
fail and assert
8 files changed, 197 insertions, 154 deletions
diff --git a/ydb/library/yaml_config/validator/fwd.h b/ydb/library/yaml_config/validator/fwd.h index 8947c3fb52..dfc6fb1812 100644 --- a/ydb/library/yaml_config/validator/fwd.h +++ b/ydb/library/yaml_config/validator/fwd.h @@ -1,5 +1,6 @@ #pragma once +#include <util/generic/yexception.h> #include <util/generic/ptr.h> namespace NYamlConfig::NValidator { @@ -41,6 +42,9 @@ class TBoolCheckContext; class TValidationResult; +class TCheckException : public yexception {}; +class TFailException : public yexception {}; + namespace NDetail { class TBuilder; diff --git a/ydb/library/yaml_config/validator/ut/validator_checks/validator_checks_ut.cpp b/ydb/library/yaml_config/validator/ut/validator_checks/validator_checks_ut.cpp index cd269f706c..0f2ce222ed 100644 --- a/ydb/library/yaml_config/validator/ut/validator_checks/validator_checks_ut.cpp +++ b/ydb/library/yaml_config/validator/ut/validator_checks/validator_checks_ut.cpp @@ -315,14 +315,13 @@ Y_UNIT_TEST_SUITE(Checks) { b.Range(0, 3); }); }) - .AddCheck("field/field/.../field level must equal /depth", [](auto& c) { + .AddCheck("field/field/.../field level must equal /depth and must be a scalar", [](auto& c) { int remaining_depth = c.Node()["depth"].Int64(); int cur_depth = 0; TNodeWrapper node = c.Node(); while (remaining_depth > 0) { if (!node.IsMap()) { - c.Expect(false, "field \"field\" on level " + ToString<i64>(cur_depth) + " must be a map"); - return; + c.Fail("field \"field\" on level " + ToString<i64>(cur_depth) + " must be a map"); } node = node.Map()["field"]; remaining_depth--; @@ -331,8 +330,7 @@ Y_UNIT_TEST_SUITE(Checks) { if (cur_depth == 0) { c.Expect(!node.Map()["field"].Exists(), "If depth == 0, field \"field\" must not be there"); } else { - c.Expect(node.Exists(), "field \"field\" on level " + ToString<i64>(cur_depth) + " must exist"); - return; + c.Assert(node.Exists(), "field \"field\" on level " + ToString<i64>(cur_depth) + " must exist"); c.Expect(node.IsScalar(), "field \"field\" on level " + ToString<i64>(cur_depth) + " must be a scalar"); } }) @@ -343,7 +341,7 @@ Y_UNIT_TEST_SUITE(Checks) { "field: value\n"; UNIT_ASSERT(HasOnlyThisIssues(v.Validate(yaml), {{ - "/", "Check \"field/field/.../field level must equal /depth\" failed: If depth == 0, field \"field\" must not be there" + "/", "Check \"field/field/.../field level must equal /depth and must be a scalar\" failed: If depth == 0, field \"field\" must not be there" }})); yaml = @@ -356,7 +354,7 @@ Y_UNIT_TEST_SUITE(Checks) { "depth: 1\n"; UNIT_ASSERT(HasOnlyThisIssues(v.Validate(yaml), {{ - "/", "Check \"field/field/.../field level must equal /depth\" failed: field \"field\" on level 1 must exist" + "/", "Check \"field/field/.../field level must equal /depth and must be a scalar\" failed: field \"field\" on level 1 must exist" }})); yaml = @@ -371,7 +369,9 @@ Y_UNIT_TEST_SUITE(Checks) { "field:\n" " field: []\n"; - UNIT_ASSERT(Valid(v.Validate(yaml))); + UNIT_ASSERT(HasOnlyThisIssues(v.Validate(yaml), {{ + "/", "Check \"field/field/.../field level must equal /depth and must be a scalar\" failed: field \"field\" on level 2 must be a scalar" + }})); yaml = "depth: 2\n" @@ -379,6 +379,8 @@ Y_UNIT_TEST_SUITE(Checks) { " field:\n" " field: value\n"; - UNIT_ASSERT(Valid(v.Validate(yaml))); + UNIT_ASSERT(HasOnlyThisIssues(v.Validate(yaml), {{ + "/", "Check \"field/field/.../field level must equal /depth and must be a scalar\" failed: field \"field\" on level 2 must be a scalar" + }})); } } diff --git a/ydb/library/yaml_config/validator/validator.cpp b/ydb/library/yaml_config/validator/validator.cpp index 13ce8a123f..586abe4a7a 100644 --- a/ydb/library/yaml_config/validator/validator.cpp +++ b/ydb/library/yaml_config/validator/validator.cpp @@ -79,8 +79,16 @@ bool TValidationResult::TIssue::operator==(const TValidationResult::TIssue& othe } TValidationResult TValidator::Validate(const TString& documentStr) { - TDocument document = TDocument::Parse(documentStr); - return Validate(document.Root()); + try { + TDocument document = TDocument::Parse(documentStr); + return Validate(document.Root()); + } catch (TFyamlEx e) { + TValidationResult validationResult; + for (const auto& error : e.Errors()) { + validationResult.Issues.emplace_back("", error); + } + return validationResult; + } } TValidator::TValidator(ENodeType nodeType) diff --git a/ydb/library/yaml_config/validator/validator.h b/ydb/library/yaml_config/validator/validator.h index 77a1561241..935dcc00ff 100644 --- a/ydb/library/yaml_config/validator/validator.h +++ b/ydb/library/yaml_config/validator/validator.h @@ -118,12 +118,14 @@ void TValidatorCommonOps<TThis, TContext>::performChecks(TValidationResult& vali TContext context(node, nodePath, This); try { checker(context); - } catch (yexception& ye) { - context.AddError(ye.what()); - context.someExpectFailed = true; + } catch (NValidator::TCheckException& e) { + context.AddError(e.what()); + context.someErrorOccured_ = true; + } catch (NValidator::TFailException& e) { + context.someErrorOccured_ = true; } - if (context.someExpectFailed) { + if (context.someErrorOccured_) { if (context.Errors_.empty()) { validationResult.AddIssue({node.Path(), checkName}); } else if (context.Errors_.size() == 1) { diff --git a/ydb/library/yaml_config/validator/validator_builder.cpp b/ydb/library/yaml_config/validator/validator_builder.cpp index 8813a60045..738e229cc8 100644 --- a/ydb/library/yaml_config/validator/validator_builder.cpp +++ b/ydb/library/yaml_config/validator/validator_builder.cpp @@ -159,7 +159,7 @@ TMapBuilder::TMapBuilder(std::function<void(TMapBuilder&)> configurator) void TMapBuilder::ThrowIfAlreadyHasField(const TString& field) { if (Children_.contains(field)) { - ythrow BuilderException() << "Node already has field \"" << field << "\""; + ythrow TBuilderException() << "Node already has field \"" << field << "\""; } } @@ -317,7 +317,7 @@ TArrayBuilder& TArrayBuilder::BoolItem(std::function<void(TBoolBuilder&)> config NDetail::TBuilder& TArrayBuilder::GetItem() { if (ItemPtr_.Get() == nullptr) { - ythrow BuilderException() << "There is no item builder yet"; + ythrow TBuilderException() << "There is no item builder yet"; } return *ItemPtr_.Get(); } diff --git a/ydb/library/yaml_config/validator/validator_builder.h b/ydb/library/yaml_config/validator/validator_builder.h index 2d56a73200..56384fedf1 100644 --- a/ydb/library/yaml_config/validator/validator_builder.h +++ b/ydb/library/yaml_config/validator/validator_builder.h @@ -15,7 +15,7 @@ namespace NYamlConfig::NValidator { -class BuilderException : public yexception {}; +class TBuilderException : public yexception {}; namespace NDetail { @@ -275,7 +275,7 @@ TThis& NDetail::TCommonBuilderOps<TThis, TCheckContext>::Configure(std::function template <typename TThis, typename TCheckContext> TThis& NDetail::TCommonBuilderOps<TThis, TCheckContext>::AddCheck(TString name, std::function<void(TCheckContext&)> checker) { if (Checkers_.contains(name)) { - ythrow yexception() << "Already has check named \"" << name << "\""; + ythrow TBuilderException() << "Already has check named \"" << name << "\""; } Checkers_[name] = checker; return AsDerived(); diff --git a/ydb/library/yaml_config/validator/validator_checks.cpp b/ydb/library/yaml_config/validator/validator_checks.cpp index def0158aa7..2f761727ea 100644 --- a/ydb/library/yaml_config/validator/validator_checks.cpp +++ b/ydb/library/yaml_config/validator/validator_checks.cpp @@ -8,40 +8,35 @@ namespace NYamlConfig::NValidator { TNodeWrapper::TNodeWrapper( - TCheckContext* context, + TCheckContext& context, NFyaml::TNodeRef node, TValidator* validator, TMaybe<ENodeType> nodeType, const TString& pathFromCheckNode) - : Context_(context) - , Node_(node) + : TBase(context, node, pathFromCheckNode) , Validator_(validator) - , NodeType_(nodeType) - , PathFromCheckNode_(pathFromCheckNode) {} + , NodeType_(nodeType) {} TGenericNodeWrapper TNodeWrapper::Generic() { // opaque nodes doesn't have validators and generic node type doesn't exist Y_ASSERT(!IsOpaqueChild()); - TGenericCheckContext* context = nullptr; TGenericValidator* validator = nullptr; if (Node_) { Y_ASSERT(NodeType_ == ENodeType::Generic); - context = static_cast<TGenericCheckContext*>(Context_); validator = static_cast<TGenericValidator*>(Validator_); } return TGenericNodeWrapper( - context, + static_cast<TGenericCheckContext&>(Context_), Node_, validator, PathFromCheckNode_); } TMapNodeWrapper TNodeWrapper::Map() { - TMapCheckContext* context = nullptr; TMapValidator* validator = nullptr; if (Node_) { @@ -49,23 +44,21 @@ TMapNodeWrapper TNodeWrapper::Map() { Y_ASSERT(NodeType_ == ENodeType::Map); } else { if (Node_.Type() != NFyaml::ENodeType::Mapping) { - throw yexception() << "Must be a map"; + throw TCheckException() << PathFromCheckNode_ << ": Must be a map"; } } - context = static_cast<TMapCheckContext*>(Context_); validator = static_cast<TMapValidator*>(Validator_); } return TMapNodeWrapper( - context, + static_cast<TMapCheckContext&>(Context_), Node_, validator, PathFromCheckNode_); } TArrayNodeWrapper TNodeWrapper::Array() { - TArrayCheckContext* context = nullptr; TArrayValidator* validator = nullptr; if (Node_) { @@ -73,91 +66,94 @@ TArrayNodeWrapper TNodeWrapper::Array() { Y_ASSERT(NodeType_ == ENodeType::Array); } else { if (Node_.Type() != NFyaml::ENodeType::Sequence) { - throw yexception() << "Must be an array"; + throw TCheckException() << PathFromCheckNode_ << ": Must be an array"; } } - context = static_cast<TArrayCheckContext*>(Context_); validator = static_cast<TArrayValidator*>(Validator_); } return TArrayNodeWrapper( - context, + static_cast<TArrayCheckContext&>(Context_), Node_, validator, PathFromCheckNode_); } +namespace { + void ThrowIfScalarNodeValidationIsNotOk(TValidationResult validationResult, TString pathFromCheckNode) { + if (!validationResult.Ok()) { + auto e = TCheckException() << pathFromCheckNode << ": " << validationResult.Issues[0].Problem; + for (int i = 1; i < validationResult.Issues.ysize(); ++i) { + e << ", " << validationResult.Issues[i].Problem; + } + + throw e; + } + } +} + TInt64NodeWrapper TNodeWrapper::Int64() { - TInt64CheckContext* context = nullptr; TInt64Validator* validator = nullptr; if (Node_) { if (!IsOpaqueChild()) { Y_ASSERT(NodeType_ == ENodeType::Int64); } else { - auto validationResult = TInt64Builder().CreateValidator().Validate(Node_); - if (!validationResult.Ok()) { - throw yexception() << validationResult; - } + ThrowIfScalarNodeValidationIsNotOk( + TInt64Builder().CreateValidator().Validate(Node_), + PathFromCheckNode_); } - context = static_cast<TInt64CheckContext*>(Context_); validator = static_cast<TInt64Validator*>(Validator_); } return TInt64NodeWrapper( - context, + static_cast<TInt64CheckContext&>(Context_), Node_, validator, PathFromCheckNode_); } TStringNodeWrapper TNodeWrapper::String() { - TStringCheckContext* context = nullptr; TStringValidator* validator = nullptr; if (Node_) { if (!IsOpaqueChild()) { Y_ASSERT(NodeType_ == ENodeType::String); } else { - auto validationResult = TStringBuilder().CreateValidator().Validate(Node_); - if (!validationResult.Ok()) { - throw yexception() << validationResult; - } + ThrowIfScalarNodeValidationIsNotOk( + TStringBuilder().CreateValidator().Validate(Node_), + PathFromCheckNode_); } - context = static_cast<TStringCheckContext*>(Context_); validator = static_cast<TStringValidator*>(Validator_); } return TStringNodeWrapper( - context, + static_cast<TStringCheckContext&>(Context_), Node_, validator, PathFromCheckNode_); } TBoolNodeWrapper TNodeWrapper::Bool() { - TBoolCheckContext* context = nullptr; TBoolValidator* validator = nullptr; if (Node_) { if (!IsOpaqueChild()) { Y_ASSERT(NodeType_ == ENodeType::Bool); } else { - auto validationResult = TBoolBuilder().CreateValidator().Validate(Node_); - if (!validationResult.Ok()) { - throw yexception() << validationResult; - } + ThrowIfScalarNodeValidationIsNotOk( + TBoolBuilder().CreateValidator().Validate(Node_), + PathFromCheckNode_); } - context = static_cast<TBoolCheckContext*>(Context_); validator = static_cast<TBoolValidator*>(Validator_); } return TBoolNodeWrapper( - context, + static_cast<TBoolCheckContext&>(Context_), Node_, validator, PathFromCheckNode_); @@ -194,23 +190,17 @@ bool TNodeWrapper::IsBool() { } bool TNodeWrapper::IsScalar() { - return IsInt64() || IsString() || IsBool(); + return IsString(); } TGenericNodeWrapper::TGenericNodeWrapper( - TGenericCheckContext* context, + TGenericCheckContext& context, NFyaml::TNodeRef node, TGenericValidator* validator, const TString& pathFromCheckNode) - : Context_(context) - , Node_(node) - , Validator_(validator) - , PathFromCheckNode_(pathFromCheckNode) { - Y_UNUSED(Validator_); - Y_UNUSED(Context_); - Y_UNUSED(Node_); - } + : TBase(context, node, pathFromCheckNode) + , Validator_(validator) {} TGenericNodeWrapper::operator TNodeWrapper() { return TNodeWrapper(Context_, Node_, Validator_, ENodeType::Generic, PathFromCheckNode_); @@ -218,14 +208,12 @@ TGenericNodeWrapper::operator TNodeWrapper() { TMapNodeWrapper::TMapNodeWrapper( - TMapCheckContext* context, + TMapCheckContext& context, NFyaml::TNodeRef node, TMapValidator* validator, const TString& pathFromCheckNode) - : Context_(context) - , Node_(node) - , Validator_(validator) - , PathFromCheckNode_(pathFromCheckNode) { + : TBase(context, node, pathFromCheckNode) + , Validator_(validator) { if (Node_) { Y_ASSERT(node.Type() == NFyaml::ENodeType::Mapping); } @@ -262,9 +250,8 @@ TNodeWrapper TMapNodeWrapper::At(const TString& field) { ThrowIfNullNode(); if (!Map().Has(field)) { - TString nodePath = Context_->CheckNodePath_ + "/" + PathFromCheckNode_; - TString message = "Node \"" + nodePath + "\" is not presented"; - throw yexception() << message; + TString message = "Node \"" + PathFromCheckNode_ + "\" is not presented"; + throw TCheckException() << message; } TValidator* validator = nullptr; @@ -273,7 +260,7 @@ TNodeWrapper TMapNodeWrapper::At(const TString& field) { if (!IsOpaqueChild()) { Y_ASSERT(Validator_); if (Validator_->Children_.contains(field)) { - validator = Validator_->Children_.at(field).Get(); + validator = Validator_->Children_[field].Get(); nodeType = validator->NodeType_; } } @@ -300,14 +287,12 @@ TMapNodeWrapper::operator TNodeWrapper() { TArrayNodeWrapper::TArrayNodeWrapper( - TArrayCheckContext* context, + TArrayCheckContext& context, NFyaml::TNodeRef node, TArrayValidator* validator, const TString& pathFromCheckNode) - : Context_(context) - , Node_(node) - , Validator_(validator) - , PathFromCheckNode_(pathFromCheckNode) { + : TBase(context, node, pathFromCheckNode) + , Validator_(validator) { Y_ASSERT(node.Type() == NFyaml::ENodeType::Sequence); } @@ -353,21 +338,19 @@ TArrayNodeWrapper::operator TNodeWrapper() { TInt64NodeWrapper::TInt64NodeWrapper( - TInt64CheckContext* context, + TInt64CheckContext& context, NFyaml::TNodeRef node, TInt64Validator* validator, const TString& pathFromCheckNode) - : Context_(context) - , Node_(node) - , Validator_(validator) - , PathFromCheckNode_(pathFromCheckNode) {} + : TBase(context, node, pathFromCheckNode) + , Validator_(validator) {} -i64 TInt64NodeWrapper::Value() { +i64 TInt64NodeWrapper::Value() const { ThrowIfNullNode(); return FromString<i64>(Node_.Scalar()); } -TInt64NodeWrapper::operator i64() { +TInt64NodeWrapper::operator i64() const { return Value(); } @@ -377,21 +360,19 @@ TInt64NodeWrapper::operator TNodeWrapper() { TStringNodeWrapper::TStringNodeWrapper( - TStringCheckContext* context, + TStringCheckContext& context, NFyaml::TNodeRef node, TStringValidator* validator, const TString& pathFromCheckNode) - : Context_(context) - , Node_(node) - , Validator_(validator) - , PathFromCheckNode_(pathFromCheckNode) {} + : TBase(context, node, pathFromCheckNode) + , Validator_(validator) {} -TString TStringNodeWrapper::Value() { +TString TStringNodeWrapper::Value() const { ThrowIfNullNode(); return Node_.Scalar(); } -TStringNodeWrapper::operator TString() { +TStringNodeWrapper::operator TString() const { return Value(); } @@ -401,23 +382,21 @@ TStringNodeWrapper::operator TNodeWrapper() { TBoolNodeWrapper::TBoolNodeWrapper( - TBoolCheckContext* context, + TBoolCheckContext& context, NFyaml::TNodeRef node, TBoolValidator* validator, const TString& pathFromCheckNode) - : Context_(context) - , Node_(node) - , Validator_(validator) - , PathFromCheckNode_(pathFromCheckNode) {} + : TBase(context, node, pathFromCheckNode) + , Validator_(validator) {} -bool TBoolNodeWrapper::Value() { +bool TBoolNodeWrapper::Value() const { ThrowIfNullNode(); TString scalar = Node_.Scalar(); scalar.to_lower(); return scalar == "true"; } -TBoolNodeWrapper::operator bool() { +TBoolNodeWrapper::operator bool() const { return Value(); } @@ -435,18 +414,39 @@ TCheckContext::TCheckContext( void TCheckContext::Expect(bool condition, TString error) { if (!condition) { AddError(error); - someExpectFailed = true; + someErrorOccured_ = true; } } void TCheckContext::Expect(bool condition) { - someExpectFailed |= !condition; + someErrorOccured_ |= !condition; } void TCheckContext::AddError(TString error) { Errors_.emplace_back(std::move(error)); } +void TCheckContext::Fail() { + throw TFailException(); +} + +void TCheckContext::Fail(TString error) { + AddError(error); + Fail(); +} + +void TCheckContext::Assert(bool condition) { + if (!condition) { + Fail(); + } +} + +void TCheckContext::Assert(bool condition, TString error) { + if (!condition) { + Fail(error); + } +} + TGenericCheckContext::TGenericCheckContext( NFyaml::TNodeRef node, const TString& checkNodePath, @@ -454,7 +454,7 @@ TGenericCheckContext::TGenericCheckContext( : TCheckContext(node, checkNodePath), Validator_(validator) {} TGenericNodeWrapper TGenericCheckContext::Node() { - return TGenericNodeWrapper(this, Node_, Validator_, CheckNodePath_); + return TGenericNodeWrapper(*this, Node_, Validator_, CheckNodePath_); } TMapCheckContext::TMapCheckContext( @@ -464,7 +464,7 @@ TMapCheckContext::TMapCheckContext( : TCheckContext(node, checkNodePath), Validator_(validator) {} TMapNodeWrapper TMapCheckContext::Node() { - return TMapNodeWrapper(this, Node_.Map(), Validator_, CheckNodePath_); + return TMapNodeWrapper(*this, Node_.Map(), Validator_, CheckNodePath_); } TArrayCheckContext::TArrayCheckContext( @@ -474,7 +474,7 @@ TArrayCheckContext::TArrayCheckContext( : TCheckContext(node, checkNodePath), Validator_(validator) {} TArrayNodeWrapper TArrayCheckContext::Node() { - return TArrayNodeWrapper(this, Node_.Sequence(), Validator_, CheckNodePath_); + return TArrayNodeWrapper(*this, Node_.Sequence(), Validator_, CheckNodePath_); } TInt64CheckContext::TInt64CheckContext( @@ -484,7 +484,7 @@ TInt64CheckContext::TInt64CheckContext( : TCheckContext(node, checkNodePath), Validator_(validator) {} TInt64NodeWrapper TInt64CheckContext::Node() { - return TInt64NodeWrapper(this, Node_, Validator_, CheckNodePath_); + return TInt64NodeWrapper(*this, Node_, Validator_, CheckNodePath_); } TStringCheckContext::TStringCheckContext( @@ -494,7 +494,7 @@ TStringCheckContext::TStringCheckContext( : TCheckContext(node, checkNodePath), Validator_(validator) {} TStringNodeWrapper TStringCheckContext::Node() { - return TStringNodeWrapper(this, Node_, Validator_, CheckNodePath_); + return TStringNodeWrapper(*this, Node_, Validator_, CheckNodePath_); } TBoolCheckContext::TBoolCheckContext( @@ -504,7 +504,7 @@ TBoolCheckContext::TBoolCheckContext( : TCheckContext(node, checkNodePath), Validator_(validator) {} TBoolNodeWrapper TBoolCheckContext::Node() { - return TBoolNodeWrapper(this, Node_, Validator_, CheckNodePath_); + return TBoolNodeWrapper(*this, Node_, Validator_, CheckNodePath_); } }
\ No newline at end of file diff --git a/ydb/library/yaml_config/validator/validator_checks.h b/ydb/library/yaml_config/validator/validator_checks.h index b68e171404..040ffeaff4 100644 --- a/ydb/library/yaml_config/validator/validator_checks.h +++ b/ydb/library/yaml_config/validator/validator_checks.h @@ -33,35 +33,65 @@ namespace NDetail { template <typename TThis> class TNodeWrapperCommonOps { public: - bool Exists(); + TNodeWrapperCommonOps(TCheckContext& context, NFyaml::TNodeRef node, TString pathFromCheckNode); + bool Exists() const; + + TNodeWrapperCommonOps<TThis>& operator=(const TNodeWrapperCommonOps<TThis>& other); protected: + TCheckContext& Context_; + NFyaml::TNodeRef Node_; + TString PathFromCheckNode_; + // if true, then has no validator, node type and can be anything - bool IsOpaqueChild(); - void ThrowIfNullNode(); + bool IsOpaqueChild() const; + void ThrowIfNullNode() const; private: + const TThis& AsDerived() const; TThis& AsDerived(); }; template <typename TThis> -void TNodeWrapperCommonOps<TThis>::ThrowIfNullNode() { - if (!AsDerived().Node_) { - throw yexception() << +TNodeWrapperCommonOps<TThis>::TNodeWrapperCommonOps( + TCheckContext& context, + NFyaml::TNodeRef node, + TString pathFromCheckNode) + : Context_(context) + , Node_(node) + , PathFromCheckNode_(pathFromCheckNode) {} + +template <typename TThis> +TNodeWrapperCommonOps<TThis>& TNodeWrapperCommonOps<TThis>::operator=(const TNodeWrapperCommonOps<TThis>& other) { + Context_ = other.Context_; + Node_ = other.Node_; + PathFromCheckNode_ = other.PathFromCheckNode_; + return *this; +} + +template <typename TThis> +void TNodeWrapperCommonOps<TThis>::ThrowIfNullNode() const { + if (!Node_) { + throw TCheckException() << "Node \"" + - AsDerived().PathFromCheckNode_ + + PathFromCheckNode_ + "\" is not presented"; } } template <typename TThis> -bool TNodeWrapperCommonOps<TThis>::IsOpaqueChild() { +bool TNodeWrapperCommonOps<TThis>::IsOpaqueChild() const { return !AsDerived().Validator_; } template <typename TThis> -bool TNodeWrapperCommonOps<TThis>::Exists() { - return AsDerived().Node_ != nullptr; +bool TNodeWrapperCommonOps<TThis>::Exists() const { + return Node_ != nullptr; +} + +template <typename TThis> +const TThis& TNodeWrapperCommonOps<TThis>::AsDerived() const { + return static_cast<const TThis&>(*this); } template <typename TThis> @@ -74,9 +104,11 @@ TThis& TNodeWrapperCommonOps<TThis>::AsDerived() { class TNodeWrapper : public NDetail::TNodeWrapperCommonOps<TNodeWrapper> { template <typename> friend class NDetail::TNodeWrapperCommonOps; + using TBase = NDetail::TNodeWrapperCommonOps<TNodeWrapper>; + public: TNodeWrapper( - TCheckContext* context, + TCheckContext& context, NFyaml::TNodeRef node, TValidator* validator, TMaybe<ENodeType> nodeType, @@ -99,20 +131,19 @@ public: bool IsScalar(); protected: - TCheckContext* Context_; - NFyaml::TNodeRef Node_; TValidator* Validator_; TMaybe<ENodeType> NodeType_; - TString PathFromCheckNode_; }; class TGenericNodeWrapper : public NDetail::TNodeWrapperCommonOps<TGenericNodeWrapper> { template <typename> friend class NDetail::TNodeWrapperCommonOps; + using TBase = NDetail::TNodeWrapperCommonOps<TGenericNodeWrapper>; + // TODO: make some functionality for generic wrapper public: TGenericNodeWrapper( - TGenericCheckContext* context, + TGenericCheckContext& context, NFyaml::TNodeRef node, TGenericValidator* validator, const TString& pathFromCheckNode); @@ -120,18 +151,17 @@ public: operator TNodeWrapper(); private: - TGenericCheckContext* Context_; - NFyaml::TNodeRef Node_; TGenericValidator* Validator_; - TString PathFromCheckNode_; }; class TMapNodeWrapper : public NDetail::TNodeWrapperCommonOps<TMapNodeWrapper> { template <typename> friend class NDetail::TNodeWrapperCommonOps; + using TBase = NDetail::TNodeWrapperCommonOps<TMapNodeWrapper>; + public: TMapNodeWrapper( - TMapCheckContext* context, + TMapCheckContext& context, NFyaml::TNodeRef node, TMapValidator* validator, const TString& pathFromCheckNode); @@ -143,10 +173,7 @@ public: bool Has(const TString& field); private: - TMapCheckContext* Context_; - NFyaml::TNodeRef Node_; TMapValidator* Validator_; - TString PathFromCheckNode_; NFyaml::TMapping Map(); }; @@ -154,9 +181,11 @@ private: class TArrayNodeWrapper : public NDetail::TNodeWrapperCommonOps<TArrayNodeWrapper> { template <typename> friend class NDetail::TNodeWrapperCommonOps; + using TBase = NDetail::TNodeWrapperCommonOps<TArrayNodeWrapper>; + public: TArrayNodeWrapper( - TArrayCheckContext* context, + TArrayCheckContext& context, NFyaml::TNodeRef node, TArrayValidator* validator, const TString& pathFromCheckNode); @@ -168,10 +197,7 @@ public: operator TNodeWrapper(); private: - TArrayCheckContext* Context_; - NFyaml::TNodeRef Node_; TArrayValidator* Validator_; - TString PathFromCheckNode_; NFyaml::TSequence Sequence(); }; @@ -179,67 +205,64 @@ private: class TInt64NodeWrapper : public NDetail::TNodeWrapperCommonOps<TInt64NodeWrapper> { template <typename> friend class NDetail::TNodeWrapperCommonOps; + using TBase = NDetail::TNodeWrapperCommonOps<TInt64NodeWrapper>; + public: TInt64NodeWrapper( - TInt64CheckContext* context, + TInt64CheckContext& context, NFyaml::TNodeRef node, TInt64Validator* validator, const TString& pathFromCheckNode); - i64 Value(); - operator i64(); + i64 Value() const; + operator i64() const; operator TNodeWrapper(); private: - TInt64CheckContext* Context_; - NFyaml::TNodeRef Node_; TInt64Validator* Validator_; - TString PathFromCheckNode_; }; class TStringNodeWrapper : public NDetail::TNodeWrapperCommonOps<TStringNodeWrapper> { template <typename> friend class NDetail::TNodeWrapperCommonOps; + using TBase = NDetail::TNodeWrapperCommonOps<TStringNodeWrapper>; + public: TStringNodeWrapper( - TStringCheckContext* context, + TStringCheckContext& context, NFyaml::TNodeRef node, TStringValidator* validator, const TString& pathFromCheckNode); - TString Value(); - operator TString(); + TString Value() const; + operator TString() const; operator TNodeWrapper(); private: - TStringCheckContext* Context_; - NFyaml::TNodeRef Node_; TStringValidator* Validator_; - TString PathFromCheckNode_; }; class TBoolNodeWrapper : public NDetail::TNodeWrapperCommonOps<TBoolNodeWrapper> { template <typename> friend class NDetail::TNodeWrapperCommonOps; + using TBase = NDetail::TNodeWrapperCommonOps<TBoolNodeWrapper>; + public: TBoolNodeWrapper( - TBoolCheckContext* context, + TBoolCheckContext& context, NFyaml::TNodeRef node, TBoolValidator* validator, const TString& pathFromCheckNode); - bool Value(); - operator bool(); + bool Value() const; + operator bool() const; operator TNodeWrapper(); private: - TBoolCheckContext* Context_; - NFyaml::TNodeRef Node_; TBoolValidator* Validator_; - TString PathFromCheckNode_; }; @@ -258,6 +281,10 @@ public: void Expect(bool condition, TString error); void Expect(bool condition); void AddError(TString error); + void Fail(TString error); + void Fail(); + void Assert(bool condition, TString error); + void Assert(bool condition); virtual ~TCheckContext() = default; @@ -265,7 +292,7 @@ protected: TVector<TString> Errors_; NFyaml::TNodeRef Node_; TString CheckNodePath_; - bool someExpectFailed = false; + bool someErrorOccured_ = false; }; class TGenericCheckContext : public TCheckContext { |