aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjansenin <jansenin@yandex-team.com>2023-08-21 13:16:41 +0300
committerjansenin <jansenin@yandex-team.com>2023-08-21 15:10:44 +0300
commitf3779eb60f392be3600b42680004f59265cfb8e0 (patch)
treea2ca771250afb32a96000be5c1da209f1b6cd58e
parent4cd60db82ef163d1c9e25435024f3289f12e0930 (diff)
downloadydb-f3779eb60f392be3600b42680004f59265cfb8e0.tar.gz
Create yaml validation framework
fix some comments and rename GeneralData_ to GeneralDataPtr_ Finished validator builders and made it compile, wrote little test Added CommonBuilderOps and TGeneralBuilder methods
-rw-r--r--ydb/library/yaml_config/CMakeLists.darwin-x86_64.txt1
-rw-r--r--ydb/library/yaml_config/CMakeLists.linux-aarch64.txt1
-rw-r--r--ydb/library/yaml_config/CMakeLists.linux-x86_64.txt1
-rw-r--r--ydb/library/yaml_config/CMakeLists.windows-x86_64.txt1
-rw-r--r--ydb/library/yaml_config/validator/CMakeLists.darwin-x86_64.txt32
-rw-r--r--ydb/library/yaml_config/validator/CMakeLists.linux-aarch64.txt33
-rw-r--r--ydb/library/yaml_config/validator/CMakeLists.linux-x86_64.txt33
-rw-r--r--ydb/library/yaml_config/validator/CMakeLists.txt17
-rw-r--r--ydb/library/yaml_config/validator/CMakeLists.windows-x86_64.txt32
-rw-r--r--ydb/library/yaml_config/validator/ut/CMakeLists.txt10
-rw-r--r--ydb/library/yaml_config/validator/ut/validator/CMakeLists.darwin-x86_64.txt62
-rw-r--r--ydb/library/yaml_config/validator/ut/validator/CMakeLists.linux-aarch64.txt67
-rw-r--r--ydb/library/yaml_config/validator/ut/validator/CMakeLists.linux-x86_64.txt69
-rw-r--r--ydb/library/yaml_config/validator/ut/validator/CMakeLists.txt17
-rw-r--r--ydb/library/yaml_config/validator/ut/validator/CMakeLists.windows-x86_64.txt57
-rw-r--r--ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp295
-rw-r--r--ydb/library/yaml_config/validator/ut/validator/ya.make11
-rw-r--r--ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.darwin-x86_64.txt62
-rw-r--r--ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.linux-aarch64.txt67
-rw-r--r--ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.linux-x86_64.txt69
-rw-r--r--ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.txt17
-rw-r--r--ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.windows-x86_64.txt57
-rw-r--r--ydb/library/yaml_config/validator/ut/validator_builder/validator_builder_ut.cpp92
-rw-r--r--ydb/library/yaml_config/validator/ut/validator_builder/ya.make11
-rw-r--r--ydb/library/yaml_config/validator/ut/ya.make4
-rw-r--r--ydb/library/yaml_config/validator/validator.cpp334
-rw-r--r--ydb/library/yaml_config/validator/validator.h183
-rw-r--r--ydb/library/yaml_config/validator/validator_builder.cpp449
-rw-r--r--ydb/library/yaml_config/validator/validator_builder.h292
-rw-r--r--ydb/library/yaml_config/validator/ya.make20
-rw-r--r--ydb/library/yaml_config/ya.make1
31 files changed, 2397 insertions, 0 deletions
diff --git a/ydb/library/yaml_config/CMakeLists.darwin-x86_64.txt b/ydb/library/yaml_config/CMakeLists.darwin-x86_64.txt
index 6925807f482..903b2701d3c 100644
--- a/ydb/library/yaml_config/CMakeLists.darwin-x86_64.txt
+++ b/ydb/library/yaml_config/CMakeLists.darwin-x86_64.txt
@@ -9,6 +9,7 @@
find_package(OpenSSL REQUIRED)
add_subdirectory(public)
add_subdirectory(ut)
+add_subdirectory(validator)
add_library(ydb-library-yaml_config)
target_link_libraries(ydb-library-yaml_config PUBLIC
diff --git a/ydb/library/yaml_config/CMakeLists.linux-aarch64.txt b/ydb/library/yaml_config/CMakeLists.linux-aarch64.txt
index 7e23908a1a7..5302caa932f 100644
--- a/ydb/library/yaml_config/CMakeLists.linux-aarch64.txt
+++ b/ydb/library/yaml_config/CMakeLists.linux-aarch64.txt
@@ -9,6 +9,7 @@
find_package(OpenSSL REQUIRED)
add_subdirectory(public)
add_subdirectory(ut)
+add_subdirectory(validator)
add_library(ydb-library-yaml_config)
target_link_libraries(ydb-library-yaml_config PUBLIC
diff --git a/ydb/library/yaml_config/CMakeLists.linux-x86_64.txt b/ydb/library/yaml_config/CMakeLists.linux-x86_64.txt
index 7e23908a1a7..5302caa932f 100644
--- a/ydb/library/yaml_config/CMakeLists.linux-x86_64.txt
+++ b/ydb/library/yaml_config/CMakeLists.linux-x86_64.txt
@@ -9,6 +9,7 @@
find_package(OpenSSL REQUIRED)
add_subdirectory(public)
add_subdirectory(ut)
+add_subdirectory(validator)
add_library(ydb-library-yaml_config)
target_link_libraries(ydb-library-yaml_config PUBLIC
diff --git a/ydb/library/yaml_config/CMakeLists.windows-x86_64.txt b/ydb/library/yaml_config/CMakeLists.windows-x86_64.txt
index 6925807f482..903b2701d3c 100644
--- a/ydb/library/yaml_config/CMakeLists.windows-x86_64.txt
+++ b/ydb/library/yaml_config/CMakeLists.windows-x86_64.txt
@@ -9,6 +9,7 @@
find_package(OpenSSL REQUIRED)
add_subdirectory(public)
add_subdirectory(ut)
+add_subdirectory(validator)
add_library(ydb-library-yaml_config)
target_link_libraries(ydb-library-yaml_config PUBLIC
diff --git a/ydb/library/yaml_config/validator/CMakeLists.darwin-x86_64.txt b/ydb/library/yaml_config/validator/CMakeLists.darwin-x86_64.txt
new file mode 100644
index 00000000000..d5bcdf7d865
--- /dev/null
+++ b/ydb/library/yaml_config/validator/CMakeLists.darwin-x86_64.txt
@@ -0,0 +1,32 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+add_subdirectory(ut)
+get_built_tool_path(
+ TOOL_enum_parser_bin
+ TOOL_enum_parser_dependency
+ tools/enum_parser/enum_parser
+ enum_parser
+)
+
+add_library(library-yaml_config-validator)
+target_link_libraries(library-yaml_config-validator PUBLIC
+ contrib-libs-cxxsupp
+ yutil
+ cpp-yaml-fyamlcpp
+ tools-enum_parser-enum_serialization_runtime
+)
+target_sources(library-yaml_config-validator PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator.cpp
+)
+generate_enum_serilization(library-yaml_config-validator
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.h
+ INCLUDE_HEADERS
+ ydb/library/yaml_config/validator/validator_builder.h
+)
diff --git a/ydb/library/yaml_config/validator/CMakeLists.linux-aarch64.txt b/ydb/library/yaml_config/validator/CMakeLists.linux-aarch64.txt
new file mode 100644
index 00000000000..5f374afe418
--- /dev/null
+++ b/ydb/library/yaml_config/validator/CMakeLists.linux-aarch64.txt
@@ -0,0 +1,33 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+add_subdirectory(ut)
+get_built_tool_path(
+ TOOL_enum_parser_bin
+ TOOL_enum_parser_dependency
+ tools/enum_parser/enum_parser
+ enum_parser
+)
+
+add_library(library-yaml_config-validator)
+target_link_libraries(library-yaml_config-validator PUBLIC
+ contrib-libs-linux-headers
+ contrib-libs-cxxsupp
+ yutil
+ cpp-yaml-fyamlcpp
+ tools-enum_parser-enum_serialization_runtime
+)
+target_sources(library-yaml_config-validator PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator.cpp
+)
+generate_enum_serilization(library-yaml_config-validator
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.h
+ INCLUDE_HEADERS
+ ydb/library/yaml_config/validator/validator_builder.h
+)
diff --git a/ydb/library/yaml_config/validator/CMakeLists.linux-x86_64.txt b/ydb/library/yaml_config/validator/CMakeLists.linux-x86_64.txt
new file mode 100644
index 00000000000..5f374afe418
--- /dev/null
+++ b/ydb/library/yaml_config/validator/CMakeLists.linux-x86_64.txt
@@ -0,0 +1,33 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+add_subdirectory(ut)
+get_built_tool_path(
+ TOOL_enum_parser_bin
+ TOOL_enum_parser_dependency
+ tools/enum_parser/enum_parser
+ enum_parser
+)
+
+add_library(library-yaml_config-validator)
+target_link_libraries(library-yaml_config-validator PUBLIC
+ contrib-libs-linux-headers
+ contrib-libs-cxxsupp
+ yutil
+ cpp-yaml-fyamlcpp
+ tools-enum_parser-enum_serialization_runtime
+)
+target_sources(library-yaml_config-validator PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator.cpp
+)
+generate_enum_serilization(library-yaml_config-validator
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.h
+ INCLUDE_HEADERS
+ ydb/library/yaml_config/validator/validator_builder.h
+)
diff --git a/ydb/library/yaml_config/validator/CMakeLists.txt b/ydb/library/yaml_config/validator/CMakeLists.txt
new file mode 100644
index 00000000000..f8b31df0c11
--- /dev/null
+++ b/ydb/library/yaml_config/validator/CMakeLists.txt
@@ -0,0 +1,17 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
+ include(CMakeLists.linux-aarch64.txt)
+elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+ include(CMakeLists.darwin-x86_64.txt)
+elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
+ include(CMakeLists.windows-x86_64.txt)
+elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
+ include(CMakeLists.linux-x86_64.txt)
+endif()
diff --git a/ydb/library/yaml_config/validator/CMakeLists.windows-x86_64.txt b/ydb/library/yaml_config/validator/CMakeLists.windows-x86_64.txt
new file mode 100644
index 00000000000..d5bcdf7d865
--- /dev/null
+++ b/ydb/library/yaml_config/validator/CMakeLists.windows-x86_64.txt
@@ -0,0 +1,32 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+add_subdirectory(ut)
+get_built_tool_path(
+ TOOL_enum_parser_bin
+ TOOL_enum_parser_dependency
+ tools/enum_parser/enum_parser
+ enum_parser
+)
+
+add_library(library-yaml_config-validator)
+target_link_libraries(library-yaml_config-validator PUBLIC
+ contrib-libs-cxxsupp
+ yutil
+ cpp-yaml-fyamlcpp
+ tools-enum_parser-enum_serialization_runtime
+)
+target_sources(library-yaml_config-validator PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator.cpp
+)
+generate_enum_serilization(library-yaml_config-validator
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/validator_builder.h
+ INCLUDE_HEADERS
+ ydb/library/yaml_config/validator/validator_builder.h
+)
diff --git a/ydb/library/yaml_config/validator/ut/CMakeLists.txt b/ydb/library/yaml_config/validator/ut/CMakeLists.txt
new file mode 100644
index 00000000000..67a3b0888d2
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/CMakeLists.txt
@@ -0,0 +1,10 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+add_subdirectory(validator)
+add_subdirectory(validator_builder)
diff --git a/ydb/library/yaml_config/validator/ut/validator/CMakeLists.darwin-x86_64.txt b/ydb/library/yaml_config/validator/ut/validator/CMakeLists.darwin-x86_64.txt
new file mode 100644
index 00000000000..ed0bb812349
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/validator/CMakeLists.darwin-x86_64.txt
@@ -0,0 +1,62 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_executable(ydb-library-yaml_config-validator-ut-validator)
+target_link_libraries(ydb-library-yaml_config-validator-ut-validator PUBLIC
+ contrib-libs-cxxsupp
+ yutil
+ library-cpp-cpuid_check
+ cpp-testing-unittest_main
+ library-yaml_config-validator
+)
+target_link_options(ydb-library-yaml_config-validator-ut-validator PRIVATE
+ -Wl,-platform_version,macos,11.0,11.0
+ -fPIC
+ -fPIC
+)
+target_sources(ydb-library-yaml_config-validator-ut-validator PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp
+)
+set_property(
+ TARGET
+ ydb-library-yaml_config-validator-ut-validator
+ PROPERTY
+ SPLIT_FACTOR
+ 1
+)
+add_yunittest(
+ NAME
+ ydb-library-yaml_config-validator-ut-validator
+ TEST_TARGET
+ ydb-library-yaml_config-validator-ut-validator
+ TEST_ARG
+ --print-before-suite
+ --print-before-test
+ --fork-tests
+ --print-times
+ --show-fails
+)
+set_yunittest_property(
+ TEST
+ ydb-library-yaml_config-validator-ut-validator
+ PROPERTY
+ LABELS
+ SMALL
+)
+set_yunittest_property(
+ TEST
+ ydb-library-yaml_config-validator-ut-validator
+ PROPERTY
+ PROCESSORS
+ 1
+)
+target_allocator(ydb-library-yaml_config-validator-ut-validator
+ system_allocator
+)
+vcs_info(ydb-library-yaml_config-validator-ut-validator)
diff --git a/ydb/library/yaml_config/validator/ut/validator/CMakeLists.linux-aarch64.txt b/ydb/library/yaml_config/validator/ut/validator/CMakeLists.linux-aarch64.txt
new file mode 100644
index 00000000000..fb8cd834369
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/validator/CMakeLists.linux-aarch64.txt
@@ -0,0 +1,67 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_executable(ydb-library-yaml_config-validator-ut-validator)
+target_link_libraries(ydb-library-yaml_config-validator-ut-validator PUBLIC
+ contrib-libs-linux-headers
+ contrib-libs-cxxsupp
+ yutil
+ cpp-testing-unittest_main
+ library-yaml_config-validator
+)
+target_link_options(ydb-library-yaml_config-validator-ut-validator PRIVATE
+ -ldl
+ -lrt
+ -Wl,--no-as-needed
+ -fPIC
+ -fPIC
+ -lpthread
+ -lrt
+ -ldl
+)
+target_sources(ydb-library-yaml_config-validator-ut-validator PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp
+)
+set_property(
+ TARGET
+ ydb-library-yaml_config-validator-ut-validator
+ PROPERTY
+ SPLIT_FACTOR
+ 1
+)
+add_yunittest(
+ NAME
+ ydb-library-yaml_config-validator-ut-validator
+ TEST_TARGET
+ ydb-library-yaml_config-validator-ut-validator
+ TEST_ARG
+ --print-before-suite
+ --print-before-test
+ --fork-tests
+ --print-times
+ --show-fails
+)
+set_yunittest_property(
+ TEST
+ ydb-library-yaml_config-validator-ut-validator
+ PROPERTY
+ LABELS
+ SMALL
+)
+set_yunittest_property(
+ TEST
+ ydb-library-yaml_config-validator-ut-validator
+ PROPERTY
+ PROCESSORS
+ 1
+)
+target_allocator(ydb-library-yaml_config-validator-ut-validator
+ cpp-malloc-jemalloc
+)
+vcs_info(ydb-library-yaml_config-validator-ut-validator)
diff --git a/ydb/library/yaml_config/validator/ut/validator/CMakeLists.linux-x86_64.txt b/ydb/library/yaml_config/validator/ut/validator/CMakeLists.linux-x86_64.txt
new file mode 100644
index 00000000000..6017dd9f835
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/validator/CMakeLists.linux-x86_64.txt
@@ -0,0 +1,69 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_executable(ydb-library-yaml_config-validator-ut-validator)
+target_link_libraries(ydb-library-yaml_config-validator-ut-validator PUBLIC
+ contrib-libs-linux-headers
+ contrib-libs-cxxsupp
+ yutil
+ library-cpp-cpuid_check
+ cpp-testing-unittest_main
+ library-yaml_config-validator
+)
+target_link_options(ydb-library-yaml_config-validator-ut-validator PRIVATE
+ -ldl
+ -lrt
+ -Wl,--no-as-needed
+ -fPIC
+ -fPIC
+ -lpthread
+ -lrt
+ -ldl
+)
+target_sources(ydb-library-yaml_config-validator-ut-validator PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp
+)
+set_property(
+ TARGET
+ ydb-library-yaml_config-validator-ut-validator
+ PROPERTY
+ SPLIT_FACTOR
+ 1
+)
+add_yunittest(
+ NAME
+ ydb-library-yaml_config-validator-ut-validator
+ TEST_TARGET
+ ydb-library-yaml_config-validator-ut-validator
+ TEST_ARG
+ --print-before-suite
+ --print-before-test
+ --fork-tests
+ --print-times
+ --show-fails
+)
+set_yunittest_property(
+ TEST
+ ydb-library-yaml_config-validator-ut-validator
+ PROPERTY
+ LABELS
+ SMALL
+)
+set_yunittest_property(
+ TEST
+ ydb-library-yaml_config-validator-ut-validator
+ PROPERTY
+ PROCESSORS
+ 1
+)
+target_allocator(ydb-library-yaml_config-validator-ut-validator
+ cpp-malloc-tcmalloc
+ libs-tcmalloc-no_percpu_cache
+)
+vcs_info(ydb-library-yaml_config-validator-ut-validator)
diff --git a/ydb/library/yaml_config/validator/ut/validator/CMakeLists.txt b/ydb/library/yaml_config/validator/ut/validator/CMakeLists.txt
new file mode 100644
index 00000000000..f8b31df0c11
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/validator/CMakeLists.txt
@@ -0,0 +1,17 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
+ include(CMakeLists.linux-aarch64.txt)
+elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+ include(CMakeLists.darwin-x86_64.txt)
+elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
+ include(CMakeLists.windows-x86_64.txt)
+elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
+ include(CMakeLists.linux-x86_64.txt)
+endif()
diff --git a/ydb/library/yaml_config/validator/ut/validator/CMakeLists.windows-x86_64.txt b/ydb/library/yaml_config/validator/ut/validator/CMakeLists.windows-x86_64.txt
new file mode 100644
index 00000000000..65ef01ab15f
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/validator/CMakeLists.windows-x86_64.txt
@@ -0,0 +1,57 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_executable(ydb-library-yaml_config-validator-ut-validator)
+target_link_libraries(ydb-library-yaml_config-validator-ut-validator PUBLIC
+ contrib-libs-cxxsupp
+ yutil
+ library-cpp-cpuid_check
+ cpp-testing-unittest_main
+ library-yaml_config-validator
+)
+target_sources(ydb-library-yaml_config-validator-ut-validator PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp
+)
+set_property(
+ TARGET
+ ydb-library-yaml_config-validator-ut-validator
+ PROPERTY
+ SPLIT_FACTOR
+ 1
+)
+add_yunittest(
+ NAME
+ ydb-library-yaml_config-validator-ut-validator
+ TEST_TARGET
+ ydb-library-yaml_config-validator-ut-validator
+ TEST_ARG
+ --print-before-suite
+ --print-before-test
+ --fork-tests
+ --print-times
+ --show-fails
+)
+set_yunittest_property(
+ TEST
+ ydb-library-yaml_config-validator-ut-validator
+ PROPERTY
+ LABELS
+ SMALL
+)
+set_yunittest_property(
+ TEST
+ ydb-library-yaml_config-validator-ut-validator
+ PROPERTY
+ PROCESSORS
+ 1
+)
+target_allocator(ydb-library-yaml_config-validator-ut-validator
+ system_allocator
+)
+vcs_info(ydb-library-yaml_config-validator-ut-validator)
diff --git a/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp b/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp
new file mode 100644
index 00000000000..1ee6a500976
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/validator/validator_ut.cpp
@@ -0,0 +1,295 @@
+#include <util/stream/str.h>
+
+#include <library/cpp/testing/unittest/registar.h>
+
+#include <ydb/library/yaml_config/validator/validator_builder.h>
+
+using namespace NYamlConfig::NValidator;
+using TIssue = TValidationResult::TIssue;
+
+bool HasIssue(const TValidationResult& result, const TIssue& issue) {
+ for (const TIssue& i : result.Issues) {
+ if (i == issue) {
+ return true;
+ }
+ }
+ Cerr << "Doesn't have specified issue. The followin issues are presented:" << Endl;
+ Cerr << result;
+ Cerr << "------------- End of issue List" << Endl;
+ return false;
+}
+
+bool HasOneIssue(const TValidationResult& result, const TIssue& issue) {
+ if (result.Issues.size() != 1) {
+ Cerr << "Has " << result.Issues.size() << " errors" << Endl;
+ return false;
+ }
+ return HasIssue(result, issue);
+}
+
+bool HasOnlyThisIssues(TValidationResult result, TVector<TIssue> issues) {
+ if (result.Issues.size() != issues.size()) {
+ return false;
+ }
+ Sort(result.Issues);
+ Sort(issues);
+ for (size_t i = 0; i < issues.size(); ++i) {
+ if (result.Issues[i] != issues[i]) {
+ Cerr << "Issues are differend. List of actul issues:" << Endl;
+ Cerr << result;
+ Cerr << "------------- List of Expected Issues: " << Endl;
+ Cerr << TValidationResult(issues);
+ Cerr << "------------- End of issue List" << Endl;
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ContainsProblem(const TValidationResult& result, const TString& problem) {
+ for (const TIssue& i : result.Issues) {
+ if (i.Problem.Contains(problem)) {
+ return true;
+ }
+ }
+ Cerr << "Problem '" << problem << "'wasn't found" << Endl;
+ Cerr << "List of issues:" << Endl;
+ Cerr << result;
+ return false;
+}
+
+Y_UNIT_TEST_SUITE(Validator) {
+ Y_UNIT_TEST(IntValidation) {
+ TInt64Builder b;
+ b.Range(0, 10);
+ auto v = b.CreateValidator();
+
+ Y_ENSURE(HasOneIssue(v.Validate("{}"), {"/", "Node must be Scalar(Int64)"}));
+ Y_ENSURE(HasOneIssue(v.Validate("1a"), {"/", "Can't convert value to Int64"}));
+ Y_ENSURE(HasOneIssue(v.Validate("11"), {"/", "Value must be less or equal to max value(i.e <= 10)"}));
+ Y_ENSURE(HasOneIssue(v.Validate("-1"), {"/", "Value must be greater or equal to min value(i.e >= 0)"}));
+ Y_ENSURE(v.Validate("5").Ok());
+ }
+
+ Y_UNIT_TEST(BoolValidation) {
+ TBoolBuilder b;
+ auto v = b.CreateValidator();
+
+ Y_ENSURE(HasOneIssue(v.Validate("{}"), {"/", "Node must be Scalar(Bool)"}));
+ Y_ENSURE(HasOneIssue(v.Validate("a"), {"/", "Value must be either true or false"}));
+ Y_ENSURE(HasOneIssue(v.Validate("1"), {"/", "Value must be either true or false"}));
+ Y_ENSURE(HasOneIssue(v.Validate("yes"), {"/", "Value must be either true or false"}));
+
+ Y_ENSURE(v.Validate("true").Ok());
+ Y_ENSURE(v.Validate("False").Ok());
+ Y_ENSURE(v.Validate("TrUe").Ok());
+ }
+
+ Y_UNIT_TEST(StringValidation) {
+ NYamlConfig::NValidator::TStringBuilder b;
+ auto v = b.CreateValidator();
+
+ Y_ENSURE(HasOneIssue(v.Validate("{}"), {"/", "Node must be Scalar(String)"}));
+
+ Y_ENSURE(v.Validate("text").Ok());
+ Y_ENSURE(v.Validate("123").Ok());
+ }
+
+ Y_UNIT_TEST(IntArrayValidation) {
+ TArrayBuilder b;
+ b.Item(TInt64Builder().Range(0, 10));
+ // or
+ // b.Int64Item([](auto& b) { b.Range(0, 10); });
+ auto v = b.CreateValidator();
+
+ Y_ENSURE(HasOneIssue(v.Validate("{}"), {"/", "Node must be Array"}));
+ Y_ENSURE(HasOneIssue(v.Validate("[{}]"), {"/0", "Node must be Scalar(Int64)"}));
+ Y_ENSURE(HasOneIssue(v.Validate("[1a]"), {"/0", "Can't convert value to Int64"}));
+ Y_ENSURE(HasOneIssue(v.Validate("[11]"), {"/0", "Value must be less or equal to max value(i.e <= 10)"}));
+ Y_ENSURE(HasOneIssue(v.Validate("[-1]"), {"/0", "Value must be greater or equal to min value(i.e >= 0)"}));
+
+ Y_ENSURE(HasOnlyThisIssues(v.Validate("[{}, 1a, 11, -1, 5]"), {
+ {"/0", "Node must be Scalar(Int64)"},
+ {"/1", "Can't convert value to Int64"},
+ {"/2", "Value must be less or equal to max value(i.e <= 10)"},
+ {"/3", "Value must be greater or equal to min value(i.e >= 0)"},
+ }));
+
+ Y_ENSURE(v.Validate("[1, 2, 3, 3, 3]").Ok());
+ Y_ENSURE(v.Validate("[0, 10, 5]").Ok());
+ }
+
+ // Also can add nullable field support
+ Y_UNIT_TEST(MapValidation) {
+ auto v =
+ TMapBuilder()
+ .Int64("required_int")
+ .Int64("int", [](auto& b) {
+ b.Optional()
+ .Range(0, 10);
+ })
+ .Bool("bool")
+ .Array("int_array", [](auto& b) {
+ b.Int64Item([](auto& b){ b.Range(0, 10); });
+ })
+ .CreateValidator();
+
+ Y_ENSURE(HasOneIssue(v.Validate("213"), {"/", "Node must be Map"}));
+
+ {
+ TString yaml =
+ "{\n"
+ "required_int: 5,\n"
+ "int: 5,\n"
+ "bool: true,\n"
+ "int_array: [1,2,3,4,5]\n"
+ "}";
+ Y_ENSURE(v.Validate(yaml).Ok());
+ }
+
+ {
+ TString yaml =
+ "{\n"
+ "int: 5,\n"
+ "bool: true,\n"
+ "int_array: [1,2,3,4,5]\n"
+ "}";
+ Y_ENSURE(HasOneIssue(v.Validate(yaml), {"/required_int", "Node is required"}));
+ }
+
+ {
+ TString yaml =
+ "{\n"
+ "required_int: 5,\n"
+ "bool: true,\n"
+ "int_array: [1,2,3,4,5]\n"
+ "}";
+ Y_ENSURE(v.Validate(yaml).Ok());
+ }
+
+ {
+ TString yaml =
+ "{\n"
+ "required_int: 5,\n"
+ "int: -1,\n"
+ "bool: true,\n"
+ "int_array: [1,2,3,4,5]\n"
+ "}";
+ Y_ENSURE(HasOneIssue(v.Validate(yaml), {"/int", "Value must be greater or equal to min value(i.e >= 0)"}));
+ }
+
+ {
+ TString yaml =
+ "{\n"
+ "required_int: 5,\n"
+ "int: 11,\n"
+ "bool: true,\n"
+ "int_array: [1,2,3,4,5]\n"
+ "}";
+ Y_ENSURE(HasOneIssue(v.Validate(yaml), {"/int", "Value must be less or equal to max value(i.e <= 10)"}));
+ }
+
+ {
+ TString yaml =
+ "{\n"
+ "required_int: 5,\n"
+ "int: 5,\n"
+ "bool: {},\n"
+ "int_array: [1,2,3,4,5]\n"
+ "}";
+ Y_ENSURE(HasOneIssue(v.Validate(yaml), {"/bool", "Node must be Scalar(Bool)"}));
+ }
+
+ {
+ TString yaml =
+ "{\n"
+ "required_int: 5,\n"
+ "int: 5,\n"
+ "bool: not_bool,\n"
+ "int_array: [1,2,3,4,5]\n"
+ "}";
+ Y_ENSURE(HasOneIssue(v.Validate(yaml), {"/bool", "Value must be either true or false"}));
+ }
+
+ {
+ TString yaml =
+ "{\n"
+ "required_int: 5,\n"
+ "int: 5,\n"
+ "bool: true,\n"
+ "int_array: [{}, 1a, 11, -1, 5]\n"
+ "}";
+ Y_ENSURE(HasOnlyThisIssues(v.Validate(yaml), {
+ {"/int_array/0", "Node must be Scalar(Int64)"},
+ {"/int_array/1", "Can't convert value to Int64"},
+ {"/int_array/2", "Value must be less or equal to max value(i.e <= 10)"},
+ {"/int_array/3", "Value must be greater or equal to min value(i.e >= 0)"},
+ }));
+ }
+
+ {
+ TString yaml =
+ "{\n"
+ "int: -1,\n"
+ "bool: not_bool,\n"
+ "int_array: [{}, 1a, 11, -1, 5]\n"
+ "}";
+ Y_ENSURE(HasOnlyThisIssues(v.Validate(yaml), {
+ {"/required_int", "Node is required"},
+ {"/int", "Value must be greater or equal to min value(i.e >= 0)"},
+ {"/bool", "Value must be either true or false"},
+ {"/int_array/0", "Node must be Scalar(Int64)"},
+ {"/int_array/1", "Can't convert value to Int64"},
+ {"/int_array/2", "Value must be less or equal to max value(i.e <= 10)"},
+ {"/int_array/3", "Value must be greater or equal to min value(i.e >= 0)"},
+ }));
+ }
+ }
+
+ Y_UNIT_TEST(MultitypeNodeValidation) {
+ TGenericBuilder b;
+ b.CanBeBool();
+ b.CanBeInt64([](auto& b) { b.Range(0, 10); });
+ b.CanBeMap([](auto& b){
+ b.Int64("int1")
+ .Int64("int2");
+ });
+
+ auto v = b.CreateValidator();
+
+ Y_ENSURE(v.Validate("true").Ok());
+ Y_ENSURE(v.Validate("FaLsE").Ok());
+ Y_ENSURE(v.Validate("0").Ok());
+ Y_ENSURE(v.Validate("10").Ok());
+ Y_ENSURE(v.Validate("{int1: 1, int2: 2}").Ok());
+
+ // should change error mesage somehow
+ Y_ENSURE(HasOneIssue(v.Validate("akaka"), {
+ "/", "There was errors in all scenarios:\n"
+ " 1) Value must be either true or false\n"
+ " 2) Can't convert value to Int64\n"
+ " 3) Node must be Map"
+ }));
+ }
+
+ Y_UNIT_TEST(OpaqueMaps) {
+ auto b =
+ TMapBuilder()
+ .Int64("int");
+
+ auto notOpaque = b.CreateValidator();
+
+ b.Opaque();
+ auto opaque = b.CreateValidator();
+
+ Y_ENSURE(notOpaque.Validate("{int: 1}").Ok());
+ Y_ENSURE(HasOneIssue(notOpaque.Validate("{}"), {"/int", "Node is required"}));
+ Y_ENSURE(HasOneIssue(
+ notOpaque.Validate("{int: 1, int2: 2}"),
+ {"/int2", "Unexpected node"}));
+
+ Y_ENSURE(opaque.Validate("{int: 1}").Ok());
+ Y_ENSURE(HasOneIssue(opaque.Validate("{}"), {"/int", "Node is required"}));
+ Y_ENSURE(opaque.Validate("{int: 1, int2: 2}").Ok());
+ }
+}
diff --git a/ydb/library/yaml_config/validator/ut/validator/ya.make b/ydb/library/yaml_config/validator/ut/validator/ya.make
new file mode 100644
index 00000000000..d01c6cf0e77
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/validator/ya.make
@@ -0,0 +1,11 @@
+UNITTEST()
+
+SRCS(
+ validator_ut.cpp
+)
+
+PEERDIR(
+ ydb/library/yaml_config/validator
+)
+
+END()
diff --git a/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.darwin-x86_64.txt b/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.darwin-x86_64.txt
new file mode 100644
index 00000000000..7584c9fe36e
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.darwin-x86_64.txt
@@ -0,0 +1,62 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_executable(yaml_config-validator-ut-validator_builder)
+target_link_libraries(yaml_config-validator-ut-validator_builder PUBLIC
+ contrib-libs-cxxsupp
+ yutil
+ library-cpp-cpuid_check
+ cpp-testing-unittest_main
+ library-yaml_config-validator
+)
+target_link_options(yaml_config-validator-ut-validator_builder PRIVATE
+ -Wl,-platform_version,macos,11.0,11.0
+ -fPIC
+ -fPIC
+)
+target_sources(yaml_config-validator-ut-validator_builder PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/ut/validator_builder/validator_builder_ut.cpp
+)
+set_property(
+ TARGET
+ yaml_config-validator-ut-validator_builder
+ PROPERTY
+ SPLIT_FACTOR
+ 1
+)
+add_yunittest(
+ NAME
+ yaml_config-validator-ut-validator_builder
+ TEST_TARGET
+ yaml_config-validator-ut-validator_builder
+ TEST_ARG
+ --print-before-suite
+ --print-before-test
+ --fork-tests
+ --print-times
+ --show-fails
+)
+set_yunittest_property(
+ TEST
+ yaml_config-validator-ut-validator_builder
+ PROPERTY
+ LABELS
+ SMALL
+)
+set_yunittest_property(
+ TEST
+ yaml_config-validator-ut-validator_builder
+ PROPERTY
+ PROCESSORS
+ 1
+)
+target_allocator(yaml_config-validator-ut-validator_builder
+ system_allocator
+)
+vcs_info(yaml_config-validator-ut-validator_builder)
diff --git a/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.linux-aarch64.txt b/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.linux-aarch64.txt
new file mode 100644
index 00000000000..cb1b241848e
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.linux-aarch64.txt
@@ -0,0 +1,67 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_executable(yaml_config-validator-ut-validator_builder)
+target_link_libraries(yaml_config-validator-ut-validator_builder PUBLIC
+ contrib-libs-linux-headers
+ contrib-libs-cxxsupp
+ yutil
+ cpp-testing-unittest_main
+ library-yaml_config-validator
+)
+target_link_options(yaml_config-validator-ut-validator_builder PRIVATE
+ -ldl
+ -lrt
+ -Wl,--no-as-needed
+ -fPIC
+ -fPIC
+ -lpthread
+ -lrt
+ -ldl
+)
+target_sources(yaml_config-validator-ut-validator_builder PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/ut/validator_builder/validator_builder_ut.cpp
+)
+set_property(
+ TARGET
+ yaml_config-validator-ut-validator_builder
+ PROPERTY
+ SPLIT_FACTOR
+ 1
+)
+add_yunittest(
+ NAME
+ yaml_config-validator-ut-validator_builder
+ TEST_TARGET
+ yaml_config-validator-ut-validator_builder
+ TEST_ARG
+ --print-before-suite
+ --print-before-test
+ --fork-tests
+ --print-times
+ --show-fails
+)
+set_yunittest_property(
+ TEST
+ yaml_config-validator-ut-validator_builder
+ PROPERTY
+ LABELS
+ SMALL
+)
+set_yunittest_property(
+ TEST
+ yaml_config-validator-ut-validator_builder
+ PROPERTY
+ PROCESSORS
+ 1
+)
+target_allocator(yaml_config-validator-ut-validator_builder
+ cpp-malloc-jemalloc
+)
+vcs_info(yaml_config-validator-ut-validator_builder)
diff --git a/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.linux-x86_64.txt b/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.linux-x86_64.txt
new file mode 100644
index 00000000000..a3875ea50b6
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.linux-x86_64.txt
@@ -0,0 +1,69 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_executable(yaml_config-validator-ut-validator_builder)
+target_link_libraries(yaml_config-validator-ut-validator_builder PUBLIC
+ contrib-libs-linux-headers
+ contrib-libs-cxxsupp
+ yutil
+ library-cpp-cpuid_check
+ cpp-testing-unittest_main
+ library-yaml_config-validator
+)
+target_link_options(yaml_config-validator-ut-validator_builder PRIVATE
+ -ldl
+ -lrt
+ -Wl,--no-as-needed
+ -fPIC
+ -fPIC
+ -lpthread
+ -lrt
+ -ldl
+)
+target_sources(yaml_config-validator-ut-validator_builder PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/ut/validator_builder/validator_builder_ut.cpp
+)
+set_property(
+ TARGET
+ yaml_config-validator-ut-validator_builder
+ PROPERTY
+ SPLIT_FACTOR
+ 1
+)
+add_yunittest(
+ NAME
+ yaml_config-validator-ut-validator_builder
+ TEST_TARGET
+ yaml_config-validator-ut-validator_builder
+ TEST_ARG
+ --print-before-suite
+ --print-before-test
+ --fork-tests
+ --print-times
+ --show-fails
+)
+set_yunittest_property(
+ TEST
+ yaml_config-validator-ut-validator_builder
+ PROPERTY
+ LABELS
+ SMALL
+)
+set_yunittest_property(
+ TEST
+ yaml_config-validator-ut-validator_builder
+ PROPERTY
+ PROCESSORS
+ 1
+)
+target_allocator(yaml_config-validator-ut-validator_builder
+ cpp-malloc-tcmalloc
+ libs-tcmalloc-no_percpu_cache
+)
+vcs_info(yaml_config-validator-ut-validator_builder)
diff --git a/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.txt b/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.txt
new file mode 100644
index 00000000000..f8b31df0c11
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.txt
@@ -0,0 +1,17 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
+ include(CMakeLists.linux-aarch64.txt)
+elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+ include(CMakeLists.darwin-x86_64.txt)
+elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
+ include(CMakeLists.windows-x86_64.txt)
+elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
+ include(CMakeLists.linux-x86_64.txt)
+endif()
diff --git a/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.windows-x86_64.txt b/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.windows-x86_64.txt
new file mode 100644
index 00000000000..e83b948e00e
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/validator_builder/CMakeLists.windows-x86_64.txt
@@ -0,0 +1,57 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_executable(yaml_config-validator-ut-validator_builder)
+target_link_libraries(yaml_config-validator-ut-validator_builder PUBLIC
+ contrib-libs-cxxsupp
+ yutil
+ library-cpp-cpuid_check
+ cpp-testing-unittest_main
+ library-yaml_config-validator
+)
+target_sources(yaml_config-validator-ut-validator_builder PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/library/yaml_config/validator/ut/validator_builder/validator_builder_ut.cpp
+)
+set_property(
+ TARGET
+ yaml_config-validator-ut-validator_builder
+ PROPERTY
+ SPLIT_FACTOR
+ 1
+)
+add_yunittest(
+ NAME
+ yaml_config-validator-ut-validator_builder
+ TEST_TARGET
+ yaml_config-validator-ut-validator_builder
+ TEST_ARG
+ --print-before-suite
+ --print-before-test
+ --fork-tests
+ --print-times
+ --show-fails
+)
+set_yunittest_property(
+ TEST
+ yaml_config-validator-ut-validator_builder
+ PROPERTY
+ LABELS
+ SMALL
+)
+set_yunittest_property(
+ TEST
+ yaml_config-validator-ut-validator_builder
+ PROPERTY
+ PROCESSORS
+ 1
+)
+target_allocator(yaml_config-validator-ut-validator_builder
+ system_allocator
+)
+vcs_info(yaml_config-validator-ut-validator_builder)
diff --git a/ydb/library/yaml_config/validator/ut/validator_builder/validator_builder_ut.cpp b/ydb/library/yaml_config/validator/ut/validator_builder/validator_builder_ut.cpp
new file mode 100644
index 00000000000..688f491c4b9
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/validator_builder/validator_builder_ut.cpp
@@ -0,0 +1,92 @@
+#include <util/stream/str.h>
+
+#include <library/cpp/testing/unittest/registar.h>
+
+#include <ydb/library/yaml_config/validator/validator_builder.h>
+
+using namespace NYamlConfig::NValidator;
+
+Y_UNIT_TEST_SUITE(ValidatorBuilder) {
+ Y_UNIT_TEST(CanCreateAllTypesOfNodes) {
+ TGenericBuilder v0;
+ TMapBuilder v1;
+ TArrayBuilder v2;
+ TInt64Builder v3;
+ NYamlConfig::NValidator::TStringBuilder v4;
+ TBoolBuilder v5;
+ }
+
+ Y_UNIT_TEST(BuildSimpleValidator) {
+ TMapBuilder dimensions([](auto& b){
+ auto greaterThanZero = [](TInt64Builder& b) {
+ b.Min(0);
+ };
+ b.Int64("length", greaterThanZero);
+ b.Int64("width", greaterThanZero);
+ b.Int64("height", greaterThanZero);
+ });
+
+ auto tagsConfigurator = [](auto& b){
+ b.Description("Tags for the product")
+ .Optional()
+ .Unique()
+ .StringItem();
+ };
+
+ auto map = TMapBuilder()
+ .Description("Map desription")
+ .Int64("productId", [](auto& b) {
+ b.Description("TString description");
+ })
+ .String("productName", [](auto& b) {
+ b.Description("Name of the product");
+ })
+ .Int64("price", [](auto& b) {
+ b.Description("The price of the product")
+ .Min(0);
+ })
+ .Array("tags", tagsConfigurator)
+ .Field("dimensions", dimensions);
+
+ map.MapAt("dimensions").Description("product size");
+ }
+
+ Y_UNIT_TEST(CanHaveMultipleType) {
+ TGenericBuilder m;
+ m.CanBeMap();
+ m.CanBeBool();
+ m.CanBeInt64();
+ TGenericBuilder m2;
+ m2.CanBeInt64();
+ m2.CanBeBool();
+ m.CanBe(m2);
+ }
+
+ Y_UNIT_TEST(CanHaveDuplicateType) {
+ TGenericBuilder m;
+ m.CanBeMap([](auto& b){ b.Int64("int_field"); });
+ m.CanBeMap([](auto& b){ b.Int64("int_field2"); });
+ m.CanBeBool();
+ }
+
+ Y_UNIT_TEST(CreateMultitypeNode) {
+ TGenericBuilder b1;
+ b1.CanBeMap();
+ b1.CanBeInt64();
+ b1.CanBeString();
+ TGenericBuilder b2;
+ b2.CanBeInt64();
+ b2.CanBeString();
+ b2.CanBeArray();
+ TMapBuilder b3;
+ b3
+ .Int64("int_f")
+ .String("string_f")
+ .Map("map");
+ TGenericBuilder final_b;
+ final_b.CanBeInt64();
+ final_b.CanBe(b1);
+ final_b.CanBe(b2);
+ final_b.CanBe(b3);
+ }
+}
diff --git a/ydb/library/yaml_config/validator/ut/validator_builder/ya.make b/ydb/library/yaml_config/validator/ut/validator_builder/ya.make
new file mode 100644
index 00000000000..3e7691e385f
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/validator_builder/ya.make
@@ -0,0 +1,11 @@
+UNITTEST()
+
+SRCS(
+ validator_builder_ut.cpp
+)
+
+PEERDIR(
+ ydb/library/yaml_config/validator
+)
+
+END()
diff --git a/ydb/library/yaml_config/validator/ut/ya.make b/ydb/library/yaml_config/validator/ut/ya.make
new file mode 100644
index 00000000000..3a4573f2fb6
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ut/ya.make
@@ -0,0 +1,4 @@
+RECURSE_FOR_TESTS(
+ validator
+ validator_builder
+)
diff --git a/ydb/library/yaml_config/validator/validator.cpp b/ydb/library/yaml_config/validator/validator.cpp
new file mode 100644
index 00000000000..87f229daf3b
--- /dev/null
+++ b/ydb/library/yaml_config/validator/validator.cpp
@@ -0,0 +1,334 @@
+#include "validator.h"
+
+#include <util/string/cast.h>
+#include <util/system/types.h>
+
+#include <utility>
+
+using namespace NFyaml;
+
+namespace NYamlConfig::NValidator {
+
+TValidationResult::TIssue::TIssue() {}
+
+TValidationResult::TIssue::TIssue(const TString& NodePath, const TString& Problem)
+ : NodePath(NodePath)
+ , Problem(Problem) {}
+
+TValidationResult::TIssue::TIssue(TIssue&& other)
+ : NodePath(std::move(other.NodePath))
+ , Problem(std::move(other.Problem)) {}
+
+TValidationResult::TIssue::TIssue(const TIssue& other)
+ : NodePath(other.NodePath)
+ , Problem(other.Problem) {}
+
+TValidationResult::TIssue& TValidationResult::TIssue::operator=(TIssue&& other) {
+ NodePath = std::move(other.NodePath);
+ Problem = std::move(other.Problem);
+ return *this;
+}
+
+TValidationResult::TIssue& TValidationResult::TIssue::operator=(const TIssue& other) {
+ NodePath = other.NodePath;
+ Problem = other.Problem;
+ return *this;
+}
+
+TValidationResult::TValidationResult() {}
+
+TValidationResult::TValidationResult(TVector<TValidationResult::TIssue> issues)
+ : Issues(std::move(issues)) {}
+
+TValidationResult::TValidationResult(TValidationResult&& validationResult)
+ : Issues(std::move(validationResult.Issues)) {}
+
+TValidationResult::TValidationResult(const TValidationResult& validationResult)
+ : Issues(validationResult.Issues) {}
+
+TValidationResult& TValidationResult::operator=(TValidationResult&& validationResult) {
+ Issues = std::move(validationResult.Issues);
+ return *this;
+}
+
+TValidationResult& TValidationResult::operator=(const TValidationResult& validationResult) {
+ Issues = validationResult.Issues;
+ return *this;
+}
+
+bool TValidationResult::Ok() {
+ return Issues.empty();
+}
+
+void TValidationResult::AddValidationErrors(TValidationResult validationResult) {
+ for (auto& issue : validationResult.Issues) {
+ Issues.emplace_back(std::move(issue));
+ }
+}
+
+void TValidationResult::AddIssue(TIssue issue) {
+ Issues.emplace_back(std::move(issue));
+}
+
+bool TValidationResult::TIssue::operator<(const TValidationResult::TIssue& other) const {
+ return std::forward_as_tuple(Problem, NodePath) < std::forward_as_tuple(other.Problem, other.NodePath);
+}
+
+bool TValidationResult::TIssue::operator==(const TValidationResult::TIssue& other) const {
+ return std::forward_as_tuple(Problem, NodePath) == std::forward_as_tuple(other.Problem, other.NodePath);
+}
+
+TValidationResult TValidator::Validate(const TString& documentStr) {
+ TDocument document = TDocument::Parse(documentStr);
+ return Validate(document.Root());
+}
+
+TValidator::TValidator() {}
+
+TValidator::TValidator(TValidator&& validator)
+ : Required_(validator.Required_) {}
+
+TValidator::~TValidator() {}
+
+TGenericValidator::TGenericValidator() {}
+
+TGenericValidator::TGenericValidator(TGenericValidator&& validator)
+ : TValidator(std::move(validator))
+ , ValidatorPtrs_(std::move(validator.ValidatorPtrs_)) {}
+
+TValidationResult TGenericValidator::Validate(const NFyaml::TNodeRef& node) {
+ if (ValidatorPtrs_.size() == 1) {
+ return ValidatorPtrs_[0]->Validate(node);
+ }
+
+ TVector<TValidationResult> validationResults;
+
+ for (const auto& validatorPtr : ValidatorPtrs_) {
+ TValidationResult result = validatorPtr->Validate(node);
+ if (result.Ok()) {
+ return {};
+ } else {
+ validationResults.push_back(result);
+ }
+ }
+
+ TString message = "There was errors in all scenarios:\n";
+
+ int scenarioIndex = 1;
+ bool addNewLine = false;
+ for (const TValidationResult& vr : validationResults) {
+ TString validationMesage;
+ bool oneIssue = vr.Issues.size() == 1;
+ if (oneIssue) {
+ validationMesage = vr.Issues[0].Problem;
+ } else {
+ bool addNewline = false;
+ for (const TValidationResult::TIssue& issue : vr.Issues) {
+ // maybe fix for multiline messages
+ validationMesage += ToString(addNewline ? "\n" : "" ) + " - " + issue.Problem;
+ addNewline = true;
+ }
+ }
+ message += ToString(addNewLine ? "\n" : "") + " " + ToString(scenarioIndex) + ") " + (oneIssue ? "" : "\n") + validationMesage;
+ scenarioIndex++;
+ addNewLine = true;
+ }
+
+ return TVector<TValidationResult::TIssue>{{
+ node.Path(),
+ message
+ }};
+}
+
+void TGenericValidator::AddValidator(TSimpleSharedPtr<TValidator> validatorPtr) {
+ ValidatorPtrs_.emplace_back(std::move(validatorPtr));
+}
+
+TMapValidator::TMapValidator() {}
+
+TMapValidator::TMapValidator(TMapValidator&& validator)
+ : TValidator(std::move(validator))
+ , Children_(std::move(validator.Children_))
+ , Opaque_(validator.Opaque_) {}
+
+TMapValidator::TMapValidator(THashMap<TString, TSimpleSharedPtr<TValidator>>&& children, bool Opaque)
+ : Children_(std::move(children))
+ , Opaque_(Opaque) {}
+
+TValidationResult TMapValidator::Validate(const TNodeRef& node) {
+ if (node.Type() != ENodeType::Mapping) {
+ return TValidationResult({{
+ node.Path(),
+ "Node must be Map"
+ }});
+ }
+
+ TString nodePath = node.Path();
+ if (nodePath == "/") nodePath = "";
+
+ TValidationResult validationResult;
+ for (const auto& [name, validatorPtr] : Children_) {
+ TValidator& validator = *validatorPtr.Get();
+
+ if (node.Map().Has(name)) {
+ validationResult.AddValidationErrors(validator.Validate(node.Map().at(name)));
+ } else if (validator.Required_) {
+ validationResult.AddIssue({
+ nodePath + "/" + name,
+ "Node is required"
+ });
+ }
+ }
+
+ if (!Opaque_) {
+ THashSet<TString> allowed;
+ for (const auto& child : Children_) {
+ allowed.insert(child.first);
+ }
+
+ for (const auto& mapNode : node.Map()) {
+ // should check for non-scalar?
+ TString name = mapNode.Key().Scalar();
+ if (!allowed.contains(name)) {
+ validationResult.AddIssue({
+ nodePath + "/" + name,
+ "Unexpected node"
+ });
+ }
+ }
+ }
+
+ return validationResult;
+}
+
+TArrayValidator::TArrayValidator() {}
+
+TArrayValidator::TArrayValidator(TArrayValidator&& validator)
+ : TValidator(std::move(validator))
+ , ItemValidatorPtr_(std::move(validator.ItemValidatorPtr_))
+ , Unique_(validator.Unique_) {}
+
+TArrayValidator::TArrayValidator(TSimpleSharedPtr<TValidator> itemValidatorPtr, bool Unique)
+ : ItemValidatorPtr_(std::move(itemValidatorPtr)), Unique_(Unique) {}
+
+TValidationResult TArrayValidator::Validate(const TNodeRef& node) {
+ if (node.Type() != ENodeType::Sequence) {
+ return TValidationResult({{
+ node.Path(),
+ "Node must be Array"
+ }});
+ }
+
+ TValidationResult validationResult;
+ for (const auto& item : node.Sequence()) {
+ validationResult.AddValidationErrors(ItemValidatorPtr_->Validate(item));
+ }
+
+ // TODO: check uniqueness
+ Y_UNUSED(Unique_);
+ return validationResult;
+}
+
+TInt64Validator::TInt64Validator() {}
+
+TInt64Validator::TInt64Validator(TInt64Validator&& validator)
+ : TValidator(std::move(validator))
+ , Min_(validator.Min_)
+ , Max_(validator.Max_) {}
+
+TInt64Validator::TInt64Validator(i64 min, i64 max)
+ : Min_(min)
+ , Max_(max) {}
+
+TValidationResult TInt64Validator::Validate(const TNodeRef& node) {
+ if (node.Type() != ENodeType::Scalar) {
+ return TValidationResult({{
+ node.Path(),
+ "Node must be Scalar(Int64)"
+ }});
+ }
+
+ TValidationResult validationResult;
+
+ if (auto res = TryFromString<i64>(node.Scalar())) {
+ i64 intRes = res.GetRef();
+ if (Min_ > intRes) {
+ validationResult.AddIssue({
+ node.Path(),
+ TString("Value must be greater or equal to min value(i.e >= ") + ToString(Min_) + ")"
+ });
+ }
+ if (Max_ < intRes) {
+ validationResult.AddIssue({
+ node.Path(),
+ TString("Value must be less or equal to max value(i.e <= ") + ToString(Max_) + ")"
+ });
+ }
+ } else {
+ validationResult.AddIssue({
+ node.Path(),
+ "Can't convert value to Int64"
+ });
+ }
+
+ return validationResult;
+}
+
+void TInt64Validator::SetMin(i64 min) {
+ Min_ = min;
+}
+
+void TInt64Validator::SetMax(i64 max) {
+ Max_ = max;
+}
+
+TStringValidator::TStringValidator() {}
+
+TStringValidator::TStringValidator(TStringValidator&& validator)
+ : TValidator(std::move(validator)) {}
+
+TValidationResult TStringValidator::Validate(const TNodeRef& node) {
+ if (node.Type() != ENodeType::Scalar) {
+ return TValidationResult({{
+ node.Path(),
+ "Node must be Scalar(String)"
+ }});
+ }
+ return {};
+}
+
+TBoolValidator::TBoolValidator() {}
+
+TBoolValidator::TBoolValidator(TBoolValidator&& validator)
+ : TValidator(std::move(validator)) {}
+
+TValidationResult TBoolValidator::Validate(const TNodeRef& node) {
+ if (node.Type() != ENodeType::Scalar) {
+ return TValidationResult({{
+ node.Path(),
+ "Node must be Scalar(Bool)"
+ }});
+ }
+
+ TString value = node.Scalar();
+ value.to_lower(); // is this correct to_lower?
+ if (value != "true" && value != "false") {
+ return TValidationResult({{
+ node.Path(),
+ "Value must be either true or false"
+ }});
+ }
+ return {};
+}
+
+} // namespace NYamlConfig::NValidator
+
+IOutputStream& operator<<(IOutputStream& out, const NYamlConfig::NValidator::TValidationResult::TIssue& issue) {
+ return out << issue.NodePath << ": " << issue.Problem;
+}
+
+Y_DECLARE_OUT_SPEC(, NYamlConfig::NValidator::TValidationResult, out, result) {
+for (const auto& issue : result.Issues) {
+ out << issue << ";" << Endl;
+ }
+}
diff --git a/ydb/library/yaml_config/validator/validator.h b/ydb/library/yaml_config/validator/validator.h
new file mode 100644
index 00000000000..a186c32d427
--- /dev/null
+++ b/ydb/library/yaml_config/validator/validator.h
@@ -0,0 +1,183 @@
+#pragma once
+
+#include <library/cpp/yaml/fyamlcpp/fyamlcpp.h>
+
+#include <util/generic/string.h>
+#include <util/generic/vector.h>
+#include <util/generic/ptr.h>
+#include <util/stream/output.h>
+#include <util/generic/hash.h>
+#include <util/system/types.h>
+#include <util/generic/ylimits.h>
+
+namespace NYamlConfig::NValidator {
+
+class TValidator;
+class TGenericValidator;
+class TMapValidator;
+class TArrayValidator;
+class TInt64Validator;
+class TStringValidator;
+class TBoolValidator;
+
+class TGenericBuilder;
+
+namespace NDetail {
+
+class TBuilder;
+
+TSimpleSharedPtr<TValidator> CreateValidatorPtr(const TSimpleSharedPtr<NDetail::TBuilder>& builder);
+
+}
+
+class TValidationResult {
+ friend class TGenericValidator;
+ friend class TMapValidator;
+ friend class TArrayValidator;
+ friend class TInt64Validator;
+ friend class TStringValidator;
+ friend class TBoolValidator;
+
+public:
+ struct TIssue {
+ TString NodePath;
+ TString Problem;
+
+ TIssue();
+ TIssue(const TString& NodePath, const TString& Problem);
+ TIssue(const TIssue& other);
+ TIssue(TIssue&& other);
+ TIssue& operator=(TIssue&& other);
+ TIssue& operator=(const TIssue& other);
+
+ bool operator<(const TValidationResult::TIssue& other) const;
+ bool operator==(const TValidationResult::TIssue& other) const;
+ };
+
+ TValidationResult();
+ TValidationResult(TVector<TIssue> issues);
+
+ TValidationResult(const TValidationResult& validationResult);
+ TValidationResult(TValidationResult&& validationResult);
+
+ TValidationResult& operator=(TValidationResult&& validationResult);
+ TValidationResult& operator=(const TValidationResult& validationResult);
+
+ bool Ok();
+
+ TVector<TIssue> Issues;
+
+private:
+ void AddValidationErrors(TValidationResult validationResult);
+ void AddIssue(TIssue issue);
+};
+
+class TValidator {
+ friend TSimpleSharedPtr<TValidator> NYamlConfig::NValidator::NDetail::CreateValidatorPtr(const TSimpleSharedPtr<NDetail::TBuilder>& builder);
+ friend class TMapValidator; // for .Required_
+ friend class TGenericBuilder; // for .Required_
+
+public:
+ TValidator();
+
+ virtual TValidationResult Validate(const NFyaml::TNodeRef& node) = 0;
+ TValidationResult Validate(const TString& document);
+
+ virtual ~TValidator();
+
+protected:
+ TValidator(TValidator&& validator);
+
+private:
+ bool Required_ = true;
+};
+
+class TGenericValidator : public TValidator {
+public:
+ TGenericValidator();
+
+ TGenericValidator(TGenericValidator&& validator);
+
+ TValidationResult Validate(const NFyaml::TNodeRef& node) override;
+ using TValidator::Validate;
+
+ void AddValidator(TSimpleSharedPtr<TValidator> validatorPtr);
+
+private:
+ TVector<TSimpleSharedPtr<TValidator>> ValidatorPtrs_;
+};
+
+class TMapValidator : public TValidator {
+public:
+ TMapValidator();
+
+ TMapValidator(TMapValidator&& validator);
+
+ explicit TMapValidator(THashMap<TString, TSimpleSharedPtr<TValidator>>&& children, bool Opaque);
+
+ TValidationResult Validate(const NFyaml::TNodeRef& node) override;
+ using TValidator::Validate;
+
+private:
+ THashMap<TString, TSimpleSharedPtr<TValidator>> Children_;
+ bool Opaque_;
+};
+
+class TArrayValidator : public TValidator {
+public:
+ TArrayValidator();
+
+ TArrayValidator(TArrayValidator&& validator);
+
+ TArrayValidator(TSimpleSharedPtr<TValidator> itemValidatorPtr, bool Unique);
+
+ TValidationResult Validate(const NFyaml::TNodeRef& node) override;
+ using TValidator::Validate;
+
+private:
+ TSimpleSharedPtr<TValidator> ItemValidatorPtr_;
+ bool Unique_;
+};
+
+class TInt64Validator : public TValidator {
+public:
+ TInt64Validator();
+
+ TInt64Validator(TInt64Validator&& validator);
+
+ TInt64Validator(i64 min, i64 max);
+
+ TValidationResult Validate(const NFyaml::TNodeRef& node) override;
+ using TValidator::Validate;
+
+private:
+ i64 Min_ = Min<i64>();
+ i64 Max_ = Max<i64>();
+
+ void SetMin(i64 min);
+ void SetMax(i64 max);
+};
+
+class TStringValidator : public TValidator {
+public:
+ TStringValidator();
+
+ TStringValidator(TStringValidator&& validator);
+
+ TValidationResult Validate(const NFyaml::TNodeRef& node) override;
+ using TValidator::Validate;
+};
+
+class TBoolValidator : public TValidator {
+public:
+ TBoolValidator();
+
+ TBoolValidator(TBoolValidator&& validator);
+
+ TValidationResult Validate(const NFyaml::TNodeRef& node) override;
+ using TValidator::Validate;
+};
+
+} // 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
new file mode 100644
index 00000000000..df62cc82dd4
--- /dev/null
+++ b/ydb/library/yaml_config/validator/validator_builder.cpp
@@ -0,0 +1,449 @@
+#include "validator_builder.h"
+
+#include "validator.h"
+
+#include <util/system/types.h>
+
+#include <utility>
+
+namespace NYamlConfig::NValidator {
+
+namespace NDetail {
+
+TSimpleSharedPtr<TValidator> CreateValidatorPtr(const TSimpleSharedPtr<TBuilder>& builder) {
+ switch (builder->BuilderType_) {
+ case EBuilderType::Generic: {
+ TGenericValidator v = static_cast<TGenericBuilder*>(builder.Get())->CreateValidator();
+ v.Required_ = builder->Required_;
+ return TSimpleSharedPtr<TValidator>(new TGenericValidator(std::move(v)));
+ }
+ case EBuilderType::Map: {
+ TMapValidator v = static_cast<TMapBuilder*>(builder.Get())->CreateValidator();
+ v.Required_ = builder->Required_;
+ return TSimpleSharedPtr<TValidator>(new TMapValidator(std::move(v)));
+ }
+ case EBuilderType::Array: {
+ TArrayValidator v = static_cast<TArrayBuilder*>(builder.Get())->CreateValidator();
+ v.Required_ = builder->Required_;
+ return TSimpleSharedPtr<TValidator>(new TArrayValidator(std::move(v)));
+ }
+ case EBuilderType::Int64: {
+ TInt64Validator v = static_cast<TInt64Builder*>(builder.Get())->CreateValidator();
+ v.Required_ = builder->Required_;
+ return TSimpleSharedPtr<TValidator>(new TInt64Validator(std::move(v)));
+ }
+ case EBuilderType::String: {
+ TStringValidator v = static_cast<TStringBuilder*>(builder.Get())->CreateValidator();
+ v.Required_ = builder->Required_;
+ return TSimpleSharedPtr<TValidator>(new TStringValidator(std::move(v)));
+ }
+ case EBuilderType::Bool: {
+ TBoolValidator v = static_cast<TBoolBuilder*>(builder.Get())->CreateValidator();
+ v.Required_ = builder->Required_;
+ return TSimpleSharedPtr<TValidator>(new TBoolValidator(std::move(v)));
+ }
+ }
+}
+
+TBuilder::TBuilder(EBuilderType builderType)
+ : BuilderType_(builderType) {}
+
+TBuilder& TBuilder::operator=(const TBuilder& builder) {
+ Y_ASSERT(BuilderType_ == builder.BuilderType_);
+ Required_ = builder.Required_;
+ Description_ = builder.Description_;
+ return *this;
+}
+
+TBuilder& TBuilder::operator=(TBuilder&& builder) {
+ Y_ASSERT(BuilderType_ == builder.BuilderType_);
+ Required_ = builder.Required_;
+ Description_ = std::move(builder.Description_);
+ return *this;
+}
+
+} // namespace NDetail
+
+TGenericBuilder::NodeTypeAndBuilder::NodeTypeAndBuilder() {}
+
+TGenericBuilder::NodeTypeAndBuilder::NodeTypeAndBuilder(EBuilderType type, TSimpleSharedPtr<TBuilder> builder)
+ : Type(type)
+ , Builder(std::move(builder)) {}
+
+
+// TGenericBuilder
+TGenericBuilder::TGenericBuilder()
+ : TCommonBuilderOps<TGenericBuilder>(EBuilderType::Generic) {};
+
+TGenericBuilder::TGenericBuilder(const TGenericBuilder& builder)
+ : TCommonBuilderOps<TGenericBuilder>(builder)
+ , PossibleBuilderPtrs_(builder.PossibleBuilderPtrs_) {}
+
+TGenericBuilder::TGenericBuilder(TGenericBuilder&& builder)
+ : TCommonBuilderOps<TGenericBuilder>(std::move(builder))
+ , PossibleBuilderPtrs_(std::move(builder.PossibleBuilderPtrs_)) {}
+
+TGenericBuilder& TGenericBuilder::operator=(const TGenericBuilder& builder) {
+ TBuilder::operator=(builder);
+ PossibleBuilderPtrs_ = builder.PossibleBuilderPtrs_;
+ return *this;
+}
+
+TGenericBuilder& TGenericBuilder::operator=(TGenericBuilder&& builder) {
+ TBuilder::operator=(std::move(builder));
+ PossibleBuilderPtrs_ = std::move(builder.PossibleBuilderPtrs_);
+ return *this;
+}
+
+TGenericBuilder::TGenericBuilder(std::function<void(TGenericBuilder&)> configurator)
+ :TGenericBuilder() {
+ configurator(*this);
+}
+
+TGenericBuilder& TGenericBuilder::CanBeMap(std::function<void(TMapBuilder&)> configurator) {
+ PossibleBuilderPtrs_.emplace_back(new TMapBuilder(configurator));
+ return *this;
+}
+
+TGenericBuilder& TGenericBuilder::CanBeArray(std::function<void(TArrayBuilder&)> configurator) {
+ PossibleBuilderPtrs_.emplace_back(new TArrayBuilder(configurator));
+ return *this;
+}
+
+TGenericBuilder& TGenericBuilder::CanBeInt64(std::function<void(TInt64Builder&)> configurator) {
+ PossibleBuilderPtrs_.emplace_back(new TInt64Builder(configurator));
+ return *this;
+}
+
+TGenericBuilder& TGenericBuilder::CanBeString(std::function<void(TStringBuilder&)> configurator) {
+ PossibleBuilderPtrs_.emplace_back(new TStringBuilder(configurator));
+ return *this;
+}
+
+TGenericBuilder& TGenericBuilder::CanBeBool(std::function<void(TBoolBuilder&)> configurator) {
+ PossibleBuilderPtrs_.emplace_back(new TBoolBuilder(configurator));
+ return *this;
+}
+
+TGenericValidator TGenericBuilder::CreateValidator() {
+ TGenericValidator result;
+ for (const auto& builderPtr : PossibleBuilderPtrs_) {
+ result.AddValidator(NDetail::CreateValidatorPtr(builderPtr));
+ }
+
+ result.Required_ = Required_;
+
+ return result;
+}
+
+TMapBuilder::TMapBuilder()
+ : TCommonBuilderOps<TMapBuilder>(EBuilderType::Map) {}
+
+TMapBuilder::TMapBuilder(const TMapBuilder& builder)
+ : TCommonBuilderOps<TMapBuilder>(builder)
+ , Children_(builder.Children_)
+ , Opaque_(builder.Opaque_) {}
+
+TMapBuilder::TMapBuilder(TMapBuilder&& builder)
+ : TCommonBuilderOps<TMapBuilder>(std::move(builder))
+ , Children_(std::move(builder.Children_))
+ , Opaque_(builder.Opaque_) {}
+
+TMapBuilder& TMapBuilder::operator=(const TMapBuilder& builder) {
+ TBuilder::operator=(builder);
+ Children_ = builder.Children_;
+ Opaque_ = builder.Opaque_;
+ return *this;
+}
+
+TMapBuilder& TMapBuilder::operator=(TMapBuilder&& builder) {
+ TBuilder::operator=(std::move(builder));
+ Children_ = std::move(builder.Children_);
+ Opaque_ = builder.Opaque_;
+ return *this;
+}
+
+TMapBuilder::TMapBuilder(std::function<void(TMapBuilder&)> configurator)
+ :TMapBuilder() {
+ configurator(*this);
+}
+
+void TMapBuilder::ThrowIfAlreadyHasField(const TString& field) {
+ if (Children_.contains(field)) {
+ ythrow BuilderException() << "Node already has field \"" << field << "\"";
+ }
+}
+
+TMapBuilder& TMapBuilder::GenericField(const TString& field, std::function<void(TGenericBuilder&)> configurator) {
+ ThrowIfAlreadyHasField(field);
+ Children_[field] = TSimpleSharedPtr<TBuilder>(new TGenericBuilder(configurator));
+ return *this;
+}
+
+TMapBuilder& TMapBuilder::Map(const TString& field, std::function<void(TMapBuilder&)> configurator) {
+ ThrowIfAlreadyHasField(field);
+ Children_[field] = TSimpleSharedPtr<TBuilder>(new TMapBuilder(configurator));
+ return *this;
+}
+
+TMapBuilder& TMapBuilder::Array(const TString& field, std::function<void(TArrayBuilder&)> configurator) {
+ ThrowIfAlreadyHasField(field);
+ Children_[field] = TSimpleSharedPtr<TBuilder>(new TArrayBuilder(configurator));
+ return *this;
+}
+
+TMapBuilder& TMapBuilder::Int64(const TString& field, std::function<void(TInt64Builder&)> configurator) {
+ ThrowIfAlreadyHasField(field);
+ Children_[field] = TSimpleSharedPtr<TBuilder>(new TInt64Builder(configurator));
+ return *this;
+}
+
+TMapBuilder& TMapBuilder::String(const TString& field, std::function<void(TStringBuilder&)> configurator) {
+ ThrowIfAlreadyHasField(field);
+ Children_[field] = TSimpleSharedPtr<TBuilder>(new TStringBuilder(configurator));
+ return *this;
+}
+
+TMapBuilder& TMapBuilder::Bool(const TString& field, std::function<void(TBoolBuilder&)> configurator) {
+ ThrowIfAlreadyHasField(field);
+ Children_[field] = TSimpleSharedPtr<TBuilder>(new TBoolBuilder(configurator));
+ return *this;
+}
+
+TMapBuilder& TMapBuilder::Opaque() {
+ Opaque_ = true;
+ return *this;
+}
+
+TMapBuilder& TMapBuilder::NotOpaque() {
+ Opaque_ = false;
+ return *this;
+}
+
+bool TMapBuilder::HasField(const TString& field) {
+ return Children_.contains(field);
+}
+
+TGenericBuilder& TMapBuilder::GenericFieldAt(const TString& field) {
+ return static_cast<TGenericBuilder&>(*Children_.at(field).Get());
+}
+
+TMapBuilder& TMapBuilder::MapAt(const TString& field) {
+ return static_cast<TMapBuilder&>(*Children_.at(field).Get());
+}
+
+TArrayBuilder& TMapBuilder::ArrayAt(const TString& field) {
+ return static_cast<TArrayBuilder&>(*Children_.at(field).Get());
+}
+
+TInt64Builder& TMapBuilder::Int64At(const TString& field) {
+ return static_cast<TInt64Builder&>(*Children_.at(field).Get());
+}
+
+TStringBuilder& TMapBuilder::StringAt(const TString& field) {
+ return static_cast<TStringBuilder&>(*Children_.at(field).Get());
+}
+
+TBoolBuilder& TMapBuilder::BoolAt(const TString& field) {
+ return static_cast<TBoolBuilder&>(*Children_.at(field).Get());
+}
+
+TMapValidator TMapBuilder::CreateValidator() {
+ THashMap<TString, TSimpleSharedPtr<TValidator>> children;
+ for (const auto& [name, builderPtr] : Children_) {
+ children[name] = NDetail::CreateValidatorPtr(builderPtr);
+ }
+
+ return TMapValidator(std::move(children), Opaque_);
+}
+
+
+// TArrayBuilder
+TArrayBuilder::TArrayBuilder()
+ : TCommonBuilderOps<TArrayBuilder>(EBuilderType::Array) {}
+
+TArrayBuilder::TArrayBuilder(const TArrayBuilder& builder)
+ : TCommonBuilderOps<TArrayBuilder>(builder)
+ , ItemPtr_(builder.ItemPtr_)
+ , Unique_(builder.Unique_) {}
+
+TArrayBuilder::TArrayBuilder(TArrayBuilder&& builder)
+ : TCommonBuilderOps<TArrayBuilder>(std::move(builder))
+ , ItemPtr_(std::move(builder.ItemPtr_))
+ , Unique_(builder.Unique_) {}
+
+TArrayBuilder& TArrayBuilder::operator=(const TArrayBuilder& builder) {
+ TBuilder::operator=(builder);
+ ItemPtr_ = builder.ItemPtr_;
+ Unique_ = builder.Unique_;
+ return *this;
+}
+
+TArrayBuilder& TArrayBuilder::operator=(TArrayBuilder&& builder) {
+ TBuilder::operator=(std::move(builder));
+ ItemPtr_ = std::move(builder.ItemPtr_);
+ Unique_ = builder.Unique_;
+ return *this;
+}
+
+TArrayBuilder::TArrayBuilder(std::function<void(TArrayBuilder&)> configurator)
+ :TArrayBuilder() {
+ configurator(*this);
+}
+
+TArrayBuilder& TArrayBuilder::Unique() {
+ Unique_ = true;
+ return *this;
+}
+
+TArrayBuilder& TArrayBuilder::MapItem(std::function<void(TMapBuilder&)> configurator) {
+ Item(TMapBuilder(configurator));
+ return *this;
+}
+
+TArrayBuilder& TArrayBuilder::ArrayItem(std::function<void(TArrayBuilder&)> configurator) {
+ Item(TArrayBuilder(configurator));
+ return *this;
+}
+
+TArrayBuilder& TArrayBuilder::Int64Item(std::function<void(TInt64Builder&)> configurator) {
+ Item(TInt64Builder(configurator));
+ return *this;
+}
+
+TArrayBuilder& TArrayBuilder::StringItem(std::function<void(TStringBuilder&)> configurator) {
+ Item(TStringBuilder(configurator));
+ return *this;
+}
+
+TArrayBuilder& TArrayBuilder::BoolItem(std::function<void(TBoolBuilder&)> configurator) {
+ Item(TBoolBuilder(configurator));
+ return *this;
+}
+
+NDetail::TBuilder& TArrayBuilder::GetItem() {
+ if (ItemPtr_.Get() == nullptr) {
+ ythrow BuilderException() << "There is no item builder yet";
+ }
+ return *ItemPtr_.Get();
+}
+
+TArrayValidator TArrayBuilder::CreateValidator() {
+ return TArrayValidator(NDetail::CreateValidatorPtr(ItemPtr_), Unique_);
+}
+
+
+// TInt64Builder
+TInt64Builder::TInt64Builder()
+ : TCommonBuilderOps<TInt64Builder>(EBuilderType::Int64) {}
+
+TInt64Builder::TInt64Builder(const TInt64Builder& builder)
+ : TCommonBuilderOps<TInt64Builder>(builder)
+ , Min_(builder.Min_)
+ , Max_(builder.Max_) {}
+
+TInt64Builder::TInt64Builder(TInt64Builder&& builder)
+ : TCommonBuilderOps<TInt64Builder>(std::move(builder))
+ , Min_(builder.Min_)
+ , Max_(builder.Max_) {}
+
+TInt64Builder& TInt64Builder::operator=(const TInt64Builder& builder) {
+ TBuilder::operator=(builder);
+ Min_ = builder.Min_;
+ Max_ = builder.Max_;
+ return *this;
+}
+
+TInt64Builder& TInt64Builder::operator=(TInt64Builder&& builder) {
+ TBuilder::operator=(std::move(builder));
+ Min_ = builder.Min_;
+ Max_ = builder.Max_;
+ return *this;
+}
+
+TInt64Builder::TInt64Builder(std::function<void(TInt64Builder&)> configurator)
+ :TInt64Builder() {
+ configurator(*this);
+}
+
+TInt64Builder& TInt64Builder::Min(i64 min) {
+ Min_ = min;
+ return *this;
+}
+
+TInt64Builder& TInt64Builder::Max(i64 max) {
+ Max_ = max;
+ return *this;
+}
+
+TInt64Builder& TInt64Builder::Range(i64 min, i64 max) {
+ Max_ = max;
+ Min_ = min;
+ return *this;
+}
+
+TInt64Validator TInt64Builder::CreateValidator() {
+ return TInt64Validator(Min_, Max_);
+}
+
+
+// TStringBuilder
+TStringBuilder::TStringBuilder()
+ : TCommonBuilderOps<TStringBuilder>(EBuilderType::Int64) {}
+
+TStringBuilder::TStringBuilder(const TStringBuilder& builder)
+ : TCommonBuilderOps<TStringBuilder>(builder) {}
+
+TStringBuilder::TStringBuilder(TStringBuilder&& builder)
+ : TCommonBuilderOps<TStringBuilder>(std::move(builder)) {}
+
+TStringBuilder& TStringBuilder::operator=(const TStringBuilder& builder) {
+ TBuilder::operator=(builder);
+ return *this;
+}
+
+TStringBuilder& TStringBuilder::operator=(TStringBuilder&& builder) {
+ TBuilder::operator=(std::move(builder));
+ return *this;
+}
+
+TStringBuilder::TStringBuilder(std::function<void(TStringBuilder&)> configurator)
+ :TStringBuilder() {
+ configurator(*this);
+}
+
+TStringValidator TStringBuilder::CreateValidator() {
+ return TStringValidator();
+}
+
+
+// TBoolBuilder
+TBoolBuilder::TBoolBuilder()
+ : TCommonBuilderOps<TBoolBuilder>(EBuilderType::Bool) {}
+
+TBoolBuilder::TBoolBuilder(const TBoolBuilder& builder)
+ : TCommonBuilderOps<TBoolBuilder>(builder) {}
+
+TBoolBuilder::TBoolBuilder(TBoolBuilder&& builder)
+ : TCommonBuilderOps<TBoolBuilder>(std::move(builder)) {}
+
+TBoolBuilder& TBoolBuilder::operator=(const TBoolBuilder& builder) {
+ TBuilder::operator=(builder);
+ return *this;
+}
+
+TBoolBuilder& TBoolBuilder::operator=(TBoolBuilder&& builder) {
+ TBuilder::operator=(std::move(builder));
+ return *this;
+}
+
+TBoolBuilder::TBoolBuilder(std::function<void(TBoolBuilder&)> configurator)
+ :TBoolBuilder() {
+ configurator(*this);
+}
+
+TBoolValidator TBoolBuilder::CreateValidator() {
+ return TBoolValidator();
+}
+
+} // namespace NYamlConfig::NValidator
diff --git a/ydb/library/yaml_config/validator/validator_builder.h b/ydb/library/yaml_config/validator/validator_builder.h
new file mode 100644
index 00000000000..eee7b94912a
--- /dev/null
+++ b/ydb/library/yaml_config/validator/validator_builder.h
@@ -0,0 +1,292 @@
+#pragma once
+
+#include "validator.h"
+
+#include <util/generic/ptr.h>
+#include <util/generic/vector.h>
+#include <util/generic/string.h>
+#include <util/generic/hash.h>
+#include <util/string/cast.h>
+#include <util/system/types.h>
+#include <util/generic/yexception.h>
+#include <util/generic/ylimits.h>
+
+#include <functional>
+
+namespace NYamlConfig::NValidator {
+
+enum class EBuilderType {
+ Generic, Map, Array, Int64, String, Bool
+};
+
+class BuilderException : public yexception {};
+
+class TGenericBuilder;
+class TMapBuilder;
+class TArrayBuilder;
+class TInt64Builder;
+class TStringBuilder;
+class TBoolBuilder;
+
+namespace NDetail {
+
+class TBuilder;
+
+TSimpleSharedPtr<TValidator> CreateValidatorPtr(const TSimpleSharedPtr<TBuilder>& builder);
+
+class TBuilder {
+ friend TSimpleSharedPtr<TValidator> NDetail::CreateValidatorPtr(const TSimpleSharedPtr<TBuilder>& builder);
+
+public:
+ TBuilder(EBuilderType builderType);
+
+ TBuilder(const TBuilder& builder) = default;
+ TBuilder(TBuilder&& builder) = default;
+
+ TBuilder& operator=(const TBuilder& builder);
+ TBuilder& operator=(TBuilder&& builder);
+
+ virtual ~TBuilder() = default;
+
+protected:
+ const EBuilderType BuilderType_;
+ bool Required_ = true;
+ TString Description_;
+};
+
+template <typename ThisType>
+class TCommonBuilderOps : public TBuilder {
+public:
+ TCommonBuilderOps<ThisType>(EBuilderType builderType);
+ TCommonBuilderOps<ThisType>(const TBuilder& builder);
+
+ ThisType& Optional();
+ ThisType& Required();
+ ThisType& Description(const TString& description);
+
+ ThisType& Configure(std::function<void(ThisType&)> configurator = [](auto&){});
+
+private:
+ ThisType& AsDerived();
+};
+
+} // namespace NDetail
+
+class TGenericBuilder : public NDetail::TCommonBuilderOps<TGenericBuilder> {
+public:
+ TGenericBuilder();
+
+ TGenericBuilder(const TGenericBuilder& builder);
+ TGenericBuilder(TGenericBuilder&& builder);
+
+ TGenericBuilder& operator=(const TGenericBuilder& builder);
+ TGenericBuilder& operator=(TGenericBuilder&& builder);
+
+ TGenericBuilder(std::function<void(TGenericBuilder&)> configurator);
+
+ template <typename Builder>
+ TGenericBuilder& CanBe(Builder builder);
+ 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& CanBeString(std::function<void(TStringBuilder&)> configurator = [](auto&){});
+ TGenericBuilder& CanBeBool(std::function<void(TBoolBuilder&)> configurator = [](auto&){});
+
+ TGenericValidator CreateValidator();
+
+private:
+ struct NodeTypeAndBuilder {
+ EBuilderType Type;
+ TSimpleSharedPtr<TBuilder> Builder;
+
+ NodeTypeAndBuilder();
+ NodeTypeAndBuilder(EBuilderType type, TSimpleSharedPtr<TBuilder> builder);
+ };
+
+ TVector<TSimpleSharedPtr<TBuilder>> PossibleBuilderPtrs_;
+};
+
+class TMapBuilder : public NDetail::TCommonBuilderOps<TMapBuilder> {
+public:
+ TMapBuilder();
+
+ TMapBuilder(const TMapBuilder& builder);
+ TMapBuilder(TMapBuilder&& builder);
+
+ TMapBuilder& operator=(const TMapBuilder& builder);
+ TMapBuilder& operator=(TMapBuilder&& builder);
+
+ TMapBuilder(std::function<void(TMapBuilder&)> configurator);
+
+ template <typename Builder>
+ TMapBuilder& Field(const TString& field, Builder builder);
+
+ TMapBuilder& GenericField(const TString& field, std::function<void(TGenericBuilder&)> configurator = [](auto&){});
+ 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& String(const TString& field, std::function<void(TStringBuilder&)> configurator = [](auto&){});
+ TMapBuilder& Bool(const TString& field, std::function<void(TBoolBuilder&)> configurator = [](auto&){});
+
+ TMapBuilder& Opaque();
+ TMapBuilder& NotOpaque();
+
+ bool HasField(const TString& field);
+
+ TGenericBuilder& GenericFieldAt(const TString& field);
+ TMapBuilder& MapAt(const TString& field);
+ TArrayBuilder& ArrayAt(const TString& field);
+ TInt64Builder& Int64At(const TString& field);
+ TStringBuilder& StringAt(const TString& field);
+ TBoolBuilder& BoolAt(const TString& field);
+
+ TMapValidator CreateValidator();
+
+private:
+ THashMap<TString, TSimpleSharedPtr<TBuilder>> Children_;
+ bool Opaque_ = false;
+
+ void ThrowIfAlreadyHasField(const TString& field);
+};
+
+class TArrayBuilder : public NDetail::TCommonBuilderOps<TArrayBuilder> {
+public:
+ TArrayBuilder();
+
+ TArrayBuilder(const TArrayBuilder& builder);
+ TArrayBuilder(TArrayBuilder&& builder);
+
+ TArrayBuilder& operator=(const TArrayBuilder& builder);
+ TArrayBuilder& operator=(TArrayBuilder&& builder);
+
+ TArrayBuilder(std::function<void(TArrayBuilder&)> configurator);
+
+ TArrayBuilder& Unique();
+
+ template <typename Builder>
+ TArrayBuilder& Item(Builder builder);
+ 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& StringItem(std::function<void(TStringBuilder&)> configurator = [](auto&){});
+ TArrayBuilder& BoolItem(std::function<void(TBoolBuilder&)> configurator = [](auto&){});
+
+ TBuilder& GetItem();
+
+ TArrayValidator CreateValidator();
+
+private:
+ TSimpleSharedPtr<TBuilder> ItemPtr_;
+ bool Unique_ = false;
+};
+
+class TInt64Builder : public NDetail::TCommonBuilderOps<TInt64Builder> {
+public:
+ TInt64Builder();
+
+ TInt64Builder(const TInt64Builder& builder);
+ TInt64Builder(TInt64Builder&& builder);
+
+ TInt64Builder& operator=(const TInt64Builder& builder);
+ TInt64Builder& operator=(TInt64Builder&& builder);
+
+ TInt64Builder(std::function<void(TInt64Builder&)> configurator);
+
+ TInt64Builder& Min(i64 min);
+ TInt64Builder& Max(i64 max);
+ TInt64Builder& Range(i64 min, i64 max);
+
+ TInt64Validator CreateValidator();
+
+private:
+ i64 Min_ = ::Min<i64>();
+ i64 Max_ = ::Max<i64>();
+};
+
+class TStringBuilder : public NDetail::TCommonBuilderOps<TStringBuilder> {
+public:
+ TStringBuilder();
+
+ TStringBuilder(const TStringBuilder& builder);
+ TStringBuilder(TStringBuilder&& builder);
+
+ TStringBuilder& operator=(const TStringBuilder& builder);
+ TStringBuilder& operator=(TStringBuilder&& builder);
+
+ TStringBuilder(std::function<void(TStringBuilder&)> configurator);
+
+ TStringValidator CreateValidator();
+};
+
+class TBoolBuilder : public NDetail::TCommonBuilderOps<TBoolBuilder> {
+public:
+ TBoolBuilder();
+
+ TBoolBuilder(const TBoolBuilder& builder);
+ TBoolBuilder(TBoolBuilder&& builder);
+
+ TBoolBuilder& operator=(const TBoolBuilder& builder);
+ TBoolBuilder& operator=(TBoolBuilder&& builder);
+
+ TBoolBuilder(std::function<void(TBoolBuilder&)> configurator);
+
+ TBoolValidator CreateValidator();
+};
+
+template <typename ThisType>
+NDetail::TCommonBuilderOps<ThisType>::TCommonBuilderOps(EBuilderType builderType)
+ : TBuilder(builderType) {}
+
+template <typename ThisType>
+NDetail::TCommonBuilderOps<ThisType>::TCommonBuilderOps(const TBuilder& builder)
+ : TBuilder(builder) {}
+
+template <typename ThisType>
+ThisType& NDetail::TCommonBuilderOps<ThisType>::AsDerived() {
+ return static_cast<ThisType&>(*this);
+}
+
+template <typename ThisType>
+ThisType& NDetail::TCommonBuilderOps<ThisType>::Optional() {
+ Required_ = false;
+ return AsDerived();
+}
+
+template <typename ThisType>
+ThisType& NDetail::TCommonBuilderOps<ThisType>::Required() {
+ Required_ = true;
+ return AsDerived();
+}
+
+template <typename ThisType>
+ThisType& NDetail::TCommonBuilderOps<ThisType>::Description(const TString& description) {
+ Description_ = description;
+ return AsDerived();
+}
+
+template <typename ThisType>
+ThisType& NDetail::TCommonBuilderOps<ThisType>::Configure(std::function<void(ThisType&)> configurator) {
+ configurator(AsDerived());
+ return AsDerived();
+}
+
+template <typename Builder>
+TGenericBuilder& TGenericBuilder::CanBe(Builder builder) {
+ PossibleBuilderPtrs_.emplace_back(new Builder(std::move(builder)));
+ return *this;
+}
+
+template <typename Builder>
+TMapBuilder& TMapBuilder::Field(const TString& field, Builder builder) {
+ ThrowIfAlreadyHasField(field);
+ Children_[field] = TSimpleSharedPtr<TBuilder>(new Builder(std::move(builder)));
+ return *this;
+}
+
+template <typename Builder>
+TArrayBuilder& TArrayBuilder::Item(Builder builder) {
+ ItemPtr_ = MakeSimpleShared<Builder>(std::move(builder));
+ return *this;
+}
+
+} // namespace NYamlConfig::NValidator
diff --git a/ydb/library/yaml_config/validator/ya.make b/ydb/library/yaml_config/validator/ya.make
new file mode 100644
index 00000000000..d6bf8e3449b
--- /dev/null
+++ b/ydb/library/yaml_config/validator/ya.make
@@ -0,0 +1,20 @@
+LIBRARY()
+
+SRCS(
+ validator_builder.h
+ validator_builder.cpp
+ validator.h
+ validator.cpp
+)
+
+PEERDIR(
+ library/cpp/yaml/fyamlcpp
+)
+
+GENERATE_ENUM_SERIALIZATION(validator_builder.h)
+
+END()
+
+RECURSE_FOR_TESTS(
+ ut
+)
diff --git a/ydb/library/yaml_config/ya.make b/ydb/library/yaml_config/ya.make
index 3e9602ba3e1..637f71bbd9c 100644
--- a/ydb/library/yaml_config/ya.make
+++ b/ydb/library/yaml_config/ya.make
@@ -27,6 +27,7 @@ END()
RECURSE(
public
+ validator
)
RECURSE_FOR_TESTS(