aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp
diff options
context:
space:
mode:
authorilnurkh <ilnurkh@yandex-team.com>2023-07-27 13:41:56 +0300
committerilnurkh <ilnurkh@yandex-team.com>2023-07-27 13:41:56 +0300
commit1761cf17008788a7ec126e953ffe46c41721d168 (patch)
treedecb73843d5195cce15a243badf6614f1bf04909 /library/cpp
parent114da2ea902184524cac007509fbe899d8154b05 (diff)
downloadydb-1761cf17008788a7ec126e953ffe46c41721d168.tar.gz
add TryNodeFromJsonString: ability to parse object and check errors without try-catch
Diffstat (limited to 'library/cpp')
-rw-r--r--library/cpp/json/common/defs.cpp1
-rw-r--r--library/cpp/json/common/defs.h4
-rw-r--r--library/cpp/yson/node/node_io.cpp11
-rw-r--r--library/cpp/yson/node/node_io.h1
-rw-r--r--library/cpp/yson/node/node_ut.cpp13
5 files changed, 30 insertions, 0 deletions
diff --git a/library/cpp/json/common/defs.cpp b/library/cpp/json/common/defs.cpp
index da86da82e4..fbc86c0f18 100644
--- a/library/cpp/json/common/defs.cpp
+++ b/library/cpp/json/common/defs.cpp
@@ -62,6 +62,7 @@ bool TJsonCallbacks::OnEnd() {
}
void TJsonCallbacks::OnError(size_t off, TStringBuf reason) {
+ HaveErrors = true;
if (ThrowException) {
ythrow TJsonException() << "JSON error at offset " << off << " (" << reason << ")";
}
diff --git a/library/cpp/json/common/defs.h b/library/cpp/json/common/defs.h
index d3c8761bcc..ae3985508b 100644
--- a/library/cpp/json/common/defs.h
+++ b/library/cpp/json/common/defs.h
@@ -32,7 +32,11 @@ namespace NJson {
virtual bool OnEnd();
virtual void OnError(size_t off, TStringBuf reason);
+ bool GetHaveErrors() const {
+ return HaveErrors;
+ }
protected:
bool ThrowException;
+ bool HaveErrors = false;
};
}
diff --git a/library/cpp/yson/node/node_io.cpp b/library/cpp/yson/node/node_io.cpp
index 294a7f7217..26b95ef996 100644
--- a/library/cpp/yson/node/node_io.cpp
+++ b/library/cpp/yson/node/node_io.cpp
@@ -126,6 +126,17 @@ void NodeToCanonicalYsonStream(const TNode& node, IOutputStream* output, NYson::
visitor.Visit(node);
}
+bool TryNodeFromJsonString(const TStringBuf input, TNode& dst)
+{
+ TMemoryInput stream(input);
+ TNodeBuilder builder(&dst);
+ TYson2JsonCallbacksAdapter callbacks(&builder, /*throwException*/ false);
+ NJson::TJsonReaderConfig config;
+ config.DontValidateUtf8 = true;
+ NJson::ReadJson(&stream, &config, &callbacks);
+ return !callbacks.GetHaveErrors();
+}
+
TNode NodeFromJsonString(const TStringBuf input)
{
TMemoryInput stream(input);
diff --git a/library/cpp/yson/node/node_io.h b/library/cpp/yson/node/node_io.h
index 454e2b14e7..02067045b8 100644
--- a/library/cpp/yson/node/node_io.h
+++ b/library/cpp/yson/node/node_io.h
@@ -31,6 +31,7 @@ void NodeToCanonicalYsonStream(const TNode& node, IOutputStream* output, ::NYson
// Parse TNode from string in JSON format
TNode NodeFromJsonString(const TStringBuf input);
+bool TryNodeFromJsonString(const TStringBuf input, TNode& dst);
// Convert TJsonValue to TNode
TNode NodeFromJsonValue(const ::NJson::TJsonValue& input);
diff --git a/library/cpp/yson/node/node_ut.cpp b/library/cpp/yson/node/node_ut.cpp
index 448e99f575..728a926283 100644
--- a/library/cpp/yson/node/node_ut.cpp
+++ b/library/cpp/yson/node/node_ut.cpp
@@ -482,3 +482,16 @@ Y_UNIT_TEST_SUITE(YtNodeTest) {
UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<TString>(0), "yaddayadda");
}
}
+
+
+Y_UNIT_TEST_SUITE(YtNodeIoTest) {
+ Y_UNIT_TEST(FromJson) {
+ NYT::TNode node;
+ node = NYT::NodeFromJsonString("1");
+ UNIT_ASSERT_VALUES_EQUAL(node.ConvertTo<int>(), 1);
+ UNIT_ASSERT(!NYT::TryNodeFromJsonString("", node));
+ UNIT_ASSERT_VALUES_EQUAL(node.ConvertTo<int>(), 1);
+ UNIT_ASSERT_EXCEPTION(NYT::NodeFromJsonString(""), yexception);
+ UNIT_ASSERT_VALUES_EQUAL(node.ConvertTo<int>(), 1);
+ }
+}