diff options
author | jansenin <jansenin@yandex-team.com> | 2023-09-14 13:08:09 +0300 |
---|---|---|
committer | jansenin <jansenin@yandex-team.com> | 2023-09-14 13:45:01 +0300 |
commit | 0f1f383f12c12532f1fc4f3bd4cf1697a3ed5fc4 (patch) | |
tree | ad73bebd26852b276d4a1e27ae36d5a61609c9ca | |
parent | d32763a27b11f69d4d6e379d966847174fa19054 (diff) | |
download | ydb-0f1f383f12c12532f1fc4f3bd4cf1697a3ed5fc4.tar.gz |
add enums
add enums
-rw-r--r-- | ydb/library/yaml_config/validator/fwd.h | 6 | ||||
-rw-r--r-- | ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp | 12 | ||||
-rw-r--r-- | ydb/library/yaml_config/validator/validator.cpp | 32 | ||||
-rw-r--r-- | ydb/library/yaml_config/validator/validator.h | 18 | ||||
-rw-r--r-- | ydb/library/yaml_config/validator/validator_builder.cpp | 94 | ||||
-rw-r--r-- | ydb/library/yaml_config/validator/validator_builder.h | 34 | ||||
-rw-r--r-- | ydb/library/yaml_config/validator/validator_checks.cpp | 51 | ||||
-rw-r--r-- | ydb/library/yaml_config/validator/validator_checks.h | 36 |
8 files changed, 282 insertions, 1 deletions
diff --git a/ydb/library/yaml_config/validator/fwd.h b/ydb/library/yaml_config/validator/fwd.h index dfc6fb1812..d2cd28c22d 100644 --- a/ydb/library/yaml_config/validator/fwd.h +++ b/ydb/library/yaml_config/validator/fwd.h @@ -6,7 +6,7 @@ namespace NYamlConfig::NValidator { enum class ENodeType { - Generic, Map, Array, Int64, String, Bool + Generic, Map, Array, Int64, String, Bool, Enum }; class TGenericBuilder; @@ -15,6 +15,7 @@ class TArrayBuilder; class TInt64Builder; class TStringBuilder; class TBoolBuilder; +class TEnumBuilder; class TValidator; class TGenericValidator; @@ -23,6 +24,7 @@ class TArrayValidator; class TInt64Validator; class TStringValidator; class TBoolValidator; +class TEnumValidator; class TNodeWrapper; class TGenericNodeWrapper; @@ -31,6 +33,7 @@ class TArrayNodeWrapper; class TInt64NodeWrapper; class TStringNodeWrapper; class TBoolNodeWrapper; +class TEnumNodeWrapper; class TCheckContext; class TGenericCheckContext; @@ -39,6 +42,7 @@ class TArrayCheckContext; class TInt64CheckContext; class TStringCheckContext; class TBoolCheckContext; +class TEnumCheckContext; class TValidationResult; diff --git a/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp b/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp index 9c6a8b1d4f..2c9e4333e8 100644 --- a/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp +++ b/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp @@ -293,4 +293,16 @@ Y_UNIT_TEST_SUITE(Validator) { Y_ENSURE(HasOneIssue(opaque.Validate("{}"), {"/int", "Node is required"})); Y_ENSURE(opaque.Validate("{int: 1, int2: 2}").Ok()); } + + Y_UNIT_TEST(Enums) { + auto v = TEnumBuilder({"a", "b", "c"}).CreateValidator(); + + Y_ENSURE(v.Validate("a").Ok()); + Y_ENSURE(v.Validate("b").Ok()); + Y_ENSURE(v.Validate("c").Ok()); + + Y_ENSURE(HasOneIssue( + v.Validate("d"), + {"/", "Node value must be one of the following: a, b, c. (it was \"d\")"})); + } } diff --git a/ydb/library/yaml_config/validator/validator.cpp b/ydb/library/yaml_config/validator/validator.cpp index 586abe4a7a..f9bda449ab 100644 --- a/ydb/library/yaml_config/validator/validator.cpp +++ b/ydb/library/yaml_config/validator/validator.cpp @@ -1,5 +1,6 @@ #include "validator.h" +#include "util/string/vector.h" #include <util/string/cast.h> #include <util/system/types.h> @@ -374,6 +375,37 @@ TValidationResult TBoolValidator::Validate(const TNodeRef& node) { return validationResult; } +TEnumValidator::TEnumValidator() + : TBase(ENodeType::Enum) {} + +TEnumValidator::TEnumValidator(TEnumValidator&& validator) + : TBase(std::move(validator)), Items_(std::move(validator.Items_)) {} + +TValidationResult TEnumValidator::Validate(const TNodeRef& node) { + if (node.Type() != NFyaml::ENodeType::Scalar) { + return TValidationResult({{ + node.Path(), + "Node must be Scalar(Enum)" + }}); + } + + TValidationResult validationResult; + + if (!Items_.contains(node.Scalar())) { + TString variants = JoinStrings(Items_.begin(), Items_.end(), ", "); + + validationResult.Issues.push_back({ + node.Path(), + "Node value must be one of the following: " + variants + ". (it was \"" + node.Scalar() + "\")"}); + } + + if (validationResult.Ok()) { + performChecks(validationResult, node); + } + + return validationResult; +} + } // namespace NYamlConfig::NValidator IOutputStream& operator<<(IOutputStream& out, const NYamlConfig::NValidator::TValidationResult::TIssue& issue) { diff --git a/ydb/library/yaml_config/validator/validator.h b/ydb/library/yaml_config/validator/validator.h index 935dcc00ff..03c5240230 100644 --- a/ydb/library/yaml_config/validator/validator.h +++ b/ydb/library/yaml_config/validator/validator.h @@ -268,6 +268,24 @@ public: using TValidator::Validate; }; +class TEnumValidator : public NDetail::TValidatorCommonOps<TEnumValidator, TEnumCheckContext> { + friend class TEnumNodeWrapper; + friend class TEnumBuilder; + + using TBase = NDetail::TValidatorCommonOps<TEnumValidator, TEnumCheckContext>; + +public: + TEnumValidator(); + + TEnumValidator(TEnumValidator&& validator); + + TValidationResult Validate(const NFyaml::TNodeRef& node) override; + using TValidator::Validate; + +private: + THashSet<TString> Items_; +}; + } // namespace NYamlConfig::NValidator IOutputStream& operator<<(IOutputStream& out, const NYamlConfig::NValidator::TValidationResult::TIssue& issue); diff --git a/ydb/library/yaml_config/validator/validator_builder.cpp b/ydb/library/yaml_config/validator/validator_builder.cpp index 738e229cc8..8826950204 100644 --- a/ydb/library/yaml_config/validator/validator_builder.cpp +++ b/ydb/library/yaml_config/validator/validator_builder.cpp @@ -30,6 +30,9 @@ TSimpleSharedPtr<TValidator> CreateValidatorPtr(const TSimpleSharedPtr<TBuilder> case ENodeType::Bool: { return MakeSimpleShared<TBoolValidator>(static_cast<TBoolBuilder*>(builder.Get())->CreateValidator()); } + case ENodeType::Enum: { + return MakeSimpleShared<TEnumValidator>(static_cast<TEnumBuilder*>(builder.Get())->CreateValidator()); + } } } @@ -103,6 +106,11 @@ TGenericBuilder& TGenericBuilder::CanBeInt64(std::function<void(TInt64Builder&)> return *this; } +TGenericBuilder& TGenericBuilder::CanBeInt64(i64 min, i64 max) { + PossibleBuilderPtrs_.emplace_back(new TInt64Builder(min, max)); + return *this; +} + TGenericBuilder& TGenericBuilder::CanBeString(std::function<void(TStringBuilder&)> configurator) { PossibleBuilderPtrs_.emplace_back(new TStringBuilder(configurator)); return *this; @@ -113,6 +121,16 @@ TGenericBuilder& TGenericBuilder::CanBeBool(std::function<void(TBoolBuilder&)> c return *this; } +TGenericBuilder& TGenericBuilder::CanBeEnum(std::function<void(TEnumBuilder&)> configurator) { + PossibleBuilderPtrs_.emplace_back(new TEnumBuilder(configurator)); + return *this; +} + +TGenericBuilder& TGenericBuilder::CanBeEnum(THashSet<TString> items) { + PossibleBuilderPtrs_.emplace_back(new TEnumBuilder(std::move(items))); + return *this; +} + TGenericValidator TGenericBuilder::CreateValidator() { TGenericValidator result; for (const auto& builderPtr : PossibleBuilderPtrs_) { @@ -187,6 +205,12 @@ TMapBuilder& TMapBuilder::Int64(const TString& field, std::function<void(TInt64B return *this; } +TMapBuilder& TMapBuilder::Int64(const TString& field, i64 min, i64 max) { + ThrowIfAlreadyHasField(field); + Children_[field] = TSimpleSharedPtr<TBuilder>(new TInt64Builder(min, max)); + return *this; +} + TMapBuilder& TMapBuilder::String(const TString& field, std::function<void(TStringBuilder&)> configurator) { ThrowIfAlreadyHasField(field); Children_[field] = TSimpleSharedPtr<TBuilder>(new TStringBuilder(configurator)); @@ -199,6 +223,18 @@ TMapBuilder& TMapBuilder::Bool(const TString& field, std::function<void(TBoolBui return *this; } +TMapBuilder& TMapBuilder::Enum(const TString& field, std::function<void(TEnumBuilder&)> configurator) { + ThrowIfAlreadyHasField(field); + Children_[field] = TSimpleSharedPtr<TBuilder>(new TEnumBuilder(configurator)); + return *this; +} + +TMapBuilder& TMapBuilder::Enum(const TString& field, THashSet<TString> items) { + ThrowIfAlreadyHasField(field); + Children_[field] = TSimpleSharedPtr<TBuilder>(new TEnumBuilder(std::move(items))); + return *this; +} + TMapBuilder& TMapBuilder::Opaque() { Opaque_ = true; return *this; @@ -237,6 +273,10 @@ TBoolBuilder& TMapBuilder::BoolAt(const TString& field) { return static_cast<TBoolBuilder&>(*Children_.at(field).Get()); } +TEnumBuilder& TMapBuilder::EnumAt(const TString& field) { + return static_cast<TEnumBuilder&>(*Children_.at(field).Get()); +} + TMapValidator TMapBuilder::CreateValidator() { THashMap<TString, TSimpleSharedPtr<TValidator>> children; for (const auto& [name, builderPtr] : Children_) { @@ -305,6 +345,11 @@ TArrayBuilder& TArrayBuilder::Int64Item(std::function<void(TInt64Builder&)> conf return *this; } +TArrayBuilder& TArrayBuilder::Int64Item(i64 min, i64 max) { + Item(TInt64Builder(min, max)); + return *this; +} + TArrayBuilder& TArrayBuilder::StringItem(std::function<void(TStringBuilder&)> configurator) { Item(TStringBuilder(configurator)); return *this; @@ -315,6 +360,16 @@ TArrayBuilder& TArrayBuilder::BoolItem(std::function<void(TBoolBuilder&)> config return *this; } +TArrayBuilder& TArrayBuilder::EnumItem(std::function<void(TEnumBuilder&)> configurator) { + Item(TEnumBuilder(configurator)); + return *this; +} + +TArrayBuilder& TArrayBuilder::EnumItem(THashSet<TString> items) { + Item(TEnumBuilder(items)); + return *this; +} + NDetail::TBuilder& TArrayBuilder::GetItem() { if (ItemPtr_.Get() == nullptr) { ythrow TBuilderException() << "There is no item builder yet"; @@ -334,6 +389,9 @@ TArrayValidator TArrayBuilder::CreateValidator() { TInt64Builder::TInt64Builder() : TBase(ENodeType::Int64) {} +TInt64Builder::TInt64Builder(i64 min, i64 max) + : TBase(ENodeType::Int64), Min_(min), Max_(max) {} + TInt64Builder::TInt64Builder(const TInt64Builder& builder) : TBase(builder) , Min_(builder.Min_) @@ -452,4 +510,40 @@ TBoolValidator TBoolBuilder::CreateValidator() { return result; } + +// TEnumBuilder +TEnumBuilder::TEnumBuilder(THashSet<TString> items) + : TBase(ENodeType::Enum), Items_(std::move(items)) {} + +TEnumBuilder::TEnumBuilder(const TEnumBuilder& builder) + : TBase(builder), Items_(builder.Items_) {} + +TEnumBuilder::TEnumBuilder(TEnumBuilder&& builder) + : TBase(std::move(builder)), Items_(std::move(builder.Items_)) {} + +TEnumBuilder& TEnumBuilder::operator=(const TEnumBuilder& builder) { + TBuilder::operator=(builder); + Items_ = builder.Items_; + return *this; +} + +TEnumBuilder& TEnumBuilder::operator=(TEnumBuilder&& builder) { + TBuilder::operator=(std::move(builder)); + Items_ = std::move(builder.Items_); + return *this; +} + +TEnumBuilder::TEnumBuilder(std::function<void(TEnumBuilder&)> configurator) + : TBase(ENodeType::Enum) { + configurator(*this); +} + +TEnumValidator TEnumBuilder::CreateValidator() { + auto result = TEnumValidator(); + result.Checkers_ = Checkers_; + result.Required_ = Required_; + result.Items_ = Items_; + return result; +} + } // namespace NYamlConfig::NValidator diff --git a/ydb/library/yaml_config/validator/validator_builder.h b/ydb/library/yaml_config/validator/validator_builder.h index 56384fedf1..a2b6f8d741 100644 --- a/ydb/library/yaml_config/validator/validator_builder.h +++ b/ydb/library/yaml_config/validator/validator_builder.h @@ -6,6 +6,7 @@ #include <util/generic/vector.h> #include <util/generic/string.h> #include <util/generic/hash.h> +#include <util/generic/hash_set.h> #include <util/string/cast.h> #include <util/system/types.h> #include <util/generic/yexception.h> @@ -81,8 +82,11 @@ public: TGenericBuilder& CanBeMap(std::function<void(TMapBuilder&)> configurator = [](auto&){}); TGenericBuilder& CanBeArray(std::function<void(TArrayBuilder&)> configurator = [](auto&){}); TGenericBuilder& CanBeInt64(std::function<void(TInt64Builder&)> configurator = [](auto&){}); + TGenericBuilder& CanBeInt64(i64 min, i64 max); TGenericBuilder& CanBeString(std::function<void(TStringBuilder&)> configurator = [](auto&){}); TGenericBuilder& CanBeBool(std::function<void(TBoolBuilder&)> configurator = [](auto&){}); + TGenericBuilder& CanBeEnum(std::function<void(TEnumBuilder&)> configurator = [](auto&){}); + TGenericBuilder& CanBeEnum(THashSet<TString> items); TGenericValidator CreateValidator(); @@ -119,8 +123,11 @@ public: TMapBuilder& Map(const TString& field, std::function<void(TMapBuilder&)> configurator = [](auto&){}); TMapBuilder& Array(const TString& field, std::function<void(TArrayBuilder&)> configurator = [](auto&){}); TMapBuilder& Int64(const TString& field, std::function<void(TInt64Builder&)> configurator = [](auto&){}); + TMapBuilder& Int64(const TString& field, i64 min, i64 max); TMapBuilder& String(const TString& field, std::function<void(TStringBuilder&)> configurator = [](auto&){}); TMapBuilder& Bool(const TString& field, std::function<void(TBoolBuilder&)> configurator = [](auto&){}); + TMapBuilder& Enum(const TString& field, std::function<void(TEnumBuilder&)> configurator = [](auto&){}); + TMapBuilder& Enum(const TString& field, THashSet<TString> items); TMapBuilder& Opaque(); TMapBuilder& NotOpaque(); @@ -133,6 +140,7 @@ public: TInt64Builder& Int64At(const TString& field); TStringBuilder& StringAt(const TString& field); TBoolBuilder& BoolAt(const TString& field); + TEnumBuilder& EnumAt(const TString& field); TMapValidator CreateValidator(); @@ -164,8 +172,11 @@ public: TArrayBuilder& MapItem(std::function<void(TMapBuilder&)> configurator = [](auto&){}); TArrayBuilder& ArrayItem(std::function<void(TArrayBuilder&)> configurator = [](auto&){}); TArrayBuilder& Int64Item(std::function<void(TInt64Builder&)> configurator = [](auto&){}); + TArrayBuilder& Int64Item(i64 min, i64 max); TArrayBuilder& StringItem(std::function<void(TStringBuilder&)> configurator = [](auto&){}); TArrayBuilder& BoolItem(std::function<void(TBoolBuilder&)> configurator = [](auto&){}); + TArrayBuilder& EnumItem(std::function<void(TEnumBuilder&)> configurator = [](auto&){}); + TArrayBuilder& EnumItem(THashSet<TString> items); TBuilder& GetItem(); @@ -181,6 +192,7 @@ class TInt64Builder : public NDetail::TCommonBuilderOps<TInt64Builder, TInt64Che public: TInt64Builder(); + TInt64Builder(i64 min, i64 max); TInt64Builder(const TInt64Builder& builder); TInt64Builder(TInt64Builder&& builder); @@ -235,6 +247,28 @@ public: TBoolValidator CreateValidator(); }; +class TEnumBuilder : public NDetail::TCommonBuilderOps<TEnumBuilder, TEnumCheckContext> { + using TBase = NDetail::TCommonBuilderOps<TEnumBuilder, TEnumCheckContext>; + +public: + TEnumBuilder(THashSet<TString> Items_); + + TEnumBuilder(const TEnumBuilder& builder); + TEnumBuilder(TEnumBuilder&& builder); + + TEnumBuilder& operator=(const TEnumBuilder& builder); + TEnumBuilder& operator=(TEnumBuilder&& builder); + + TEnumBuilder(std::function<void(TEnumBuilder&)> configurator); + + void SetItems(const THashSet<TString>& items); + + TEnumValidator CreateValidator(); + +private: + THashSet<TString> Items_; +}; + template <typename TThis, typename TCheckContext> NDetail::TCommonBuilderOps<TThis, TCheckContext>::TCommonBuilderOps(ENodeType nodeType) : TBuilder(nodeType) {} diff --git a/ydb/library/yaml_config/validator/validator_checks.cpp b/ydb/library/yaml_config/validator/validator_checks.cpp index 2f761727ea..dbb6e17527 100644 --- a/ydb/library/yaml_config/validator/validator_checks.cpp +++ b/ydb/library/yaml_config/validator/validator_checks.cpp @@ -159,6 +159,25 @@ TBoolNodeWrapper TNodeWrapper::Bool() { PathFromCheckNode_); } +TEnumNodeWrapper TNodeWrapper::Enum() { + // opaque enum is just a string + Y_ASSERT(!IsOpaqueChild()); + + TEnumValidator* validator = nullptr; + + if (Node_) { + Y_ASSERT(NodeType_ == ENodeType::Enum); + + validator = static_cast<TEnumValidator*>(Validator_); + } + + return TEnumNodeWrapper( + static_cast<TEnumCheckContext&>(Context_), + Node_, + validator, + PathFromCheckNode_); +} + TMaybe<ENodeType> TNodeWrapper::ValidatorType() { ThrowIfNullNode(); return NodeType_; @@ -405,6 +424,28 @@ TBoolNodeWrapper::operator TNodeWrapper() { } +TEnumNodeWrapper::TEnumNodeWrapper( + TEnumCheckContext& context, + NFyaml::TNodeRef node, + TEnumValidator* validator, + const TString& pathFromCheckNode) + : TBase(context, node, pathFromCheckNode) + , Validator_(validator) {} + +TString TEnumNodeWrapper::Value() const { + ThrowIfNullNode(); + return Node_.Scalar(); +} + +TEnumNodeWrapper::operator TString() const { + return Value(); +} + +TEnumNodeWrapper::operator TNodeWrapper() { + return TNodeWrapper(Context_, Node_, Validator_, ENodeType::Bool, PathFromCheckNode_); +} + + TCheckContext::TCheckContext( NFyaml::TNodeRef node, const TString& checkNodePath) @@ -507,4 +548,14 @@ TBoolNodeWrapper TBoolCheckContext::Node() { return TBoolNodeWrapper(*this, Node_, Validator_, CheckNodePath_); } +TEnumCheckContext::TEnumCheckContext( + NFyaml::TNodeRef node, + const TString& checkNodePath, + TEnumValidator* validator) + : TCheckContext(node, checkNodePath), Validator_(validator) {} + +TEnumNodeWrapper TEnumCheckContext::Node() { + return TEnumNodeWrapper(*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 040ffeaff4..57be08bf89 100644 --- a/ydb/library/yaml_config/validator/validator_checks.h +++ b/ydb/library/yaml_config/validator/validator_checks.h @@ -120,6 +120,7 @@ public: TInt64NodeWrapper Int64(); TStringNodeWrapper String(); TBoolNodeWrapper Bool(); + TEnumNodeWrapper Enum(); TMaybe<ENodeType> ValidatorType(); @@ -265,6 +266,27 @@ private: TBoolValidator* Validator_; }; +class TEnumNodeWrapper : public NDetail::TNodeWrapperCommonOps<TEnumNodeWrapper> { + template <typename> friend class NDetail::TNodeWrapperCommonOps; + + using TBase = NDetail::TNodeWrapperCommonOps<TEnumNodeWrapper>; + +public: + TEnumNodeWrapper( + TEnumCheckContext& context, + NFyaml::TNodeRef node, + TEnumValidator* validator, + const TString& pathFromCheckNode); + + TString Value() const; + operator TString() const; + + operator TNodeWrapper(); + +private: + TEnumValidator* Validator_; +}; + class TCheckContext { friend class TMapNodeWrapper; // for access to node path @@ -383,4 +405,18 @@ private: TBoolValidator* Validator_; }; +class TEnumCheckContext : public TCheckContext { + friend class TEnumNodeWrapper; + +public: + TEnumCheckContext(NFyaml::TNodeRef node, + const TString& checkNodePath, + TEnumValidator* validator); + + TEnumNodeWrapper Node(); + +private: + TEnumValidator* Validator_; +}; + } // namespace NYamlConfig::NValidator |