aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjansenin <jansenin@yandex-team.com>2023-09-14 13:08:09 +0300
committerjansenin <jansenin@yandex-team.com>2023-09-14 13:45:01 +0300
commit0f1f383f12c12532f1fc4f3bd4cf1697a3ed5fc4 (patch)
treead73bebd26852b276d4a1e27ae36d5a61609c9ca
parentd32763a27b11f69d4d6e379d966847174fa19054 (diff)
downloadydb-0f1f383f12c12532f1fc4f3bd4cf1697a3ed5fc4.tar.gz
add enums
add enums
-rw-r--r--ydb/library/yaml_config/validator/fwd.h6
-rw-r--r--ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp12
-rw-r--r--ydb/library/yaml_config/validator/validator.cpp32
-rw-r--r--ydb/library/yaml_config/validator/validator.h18
-rw-r--r--ydb/library/yaml_config/validator/validator_builder.cpp94
-rw-r--r--ydb/library/yaml_config/validator/validator_builder.h34
-rw-r--r--ydb/library/yaml_config/validator/validator_checks.cpp51
-rw-r--r--ydb/library/yaml_config/validator/validator_checks.h36
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