aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp
diff options
context:
space:
mode:
authordddlatyshev <dddlatyshev@yandex-team.com>2023-02-22 19:30:31 +0300
committerdddlatyshev <dddlatyshev@yandex-team.com>2023-02-22 19:30:31 +0300
commite335b244b0805b9744c35500685750135c97bd8f (patch)
treea9492ee15bafec49139dbd31234defc4da8ba4c7 /library/cpp
parentd6db0fa7fd05eea98ca692ecc6bd29c2b08700c3 (diff)
downloadydb-e335b244b0805b9744c35500685750135c97bd8f.tar.gz
Add StringifyInt64Always mode
Diffstat (limited to 'library/cpp')
-rw-r--r--library/cpp/protobuf/json/config.h9
-rw-r--r--library/cpp/protobuf/json/proto2json_printer.cpp14
-rw-r--r--library/cpp/protobuf/json/ut/proto2json_ut.cpp80
3 files changed, 56 insertions, 47 deletions
diff --git a/library/cpp/protobuf/json/config.h b/library/cpp/protobuf/json/config.h
index 2ffda4a065..96bb832565 100644
--- a/library/cpp/protobuf/json/config.h
+++ b/library/cpp/protobuf/json/config.h
@@ -83,12 +83,13 @@ namespace NProtobufJson {
bool MapAsObject = false;
/// Stringify long integers which are not exactly representable by float or double values
- enum EStringifyLongNumbersMode {
+ enum EStringifyNumbersMode {
StringifyLongNumbersNever = 0, // default
StringifyLongNumbersForFloat,
StringifyLongNumbersForDouble,
+ StringifyInt64Always,
};
- EStringifyLongNumbersMode StringifyLongNumbers = StringifyLongNumbersNever;
+ EStringifyNumbersMode StringifyNumbers = StringifyLongNumbersNever;
/// Custom field names generator.
TNameGenerator NameGenerator = {};
@@ -170,8 +171,8 @@ namespace NProtobufJson {
return *this;
}
- TSelf& SetStringifyLongNumbers(EStringifyLongNumbersMode stringify) {
- StringifyLongNumbers = stringify;
+ TSelf& SetStringifyNumbers(EStringifyNumbersMode stringify) {
+ StringifyNumbers = stringify;
return *this;
}
diff --git a/library/cpp/protobuf/json/proto2json_printer.cpp b/library/cpp/protobuf/json/proto2json_printer.cpp
index 6ec7800ad3..6663ac6e71 100644
--- a/library/cpp/protobuf/json/proto2json_printer.cpp
+++ b/library/cpp/protobuf/json/proto2json_printer.cpp
@@ -466,8 +466,6 @@ namespace NProtobufJson {
const FieldDescriptor& field,
IJsonOutput& json,
const TStringBuf key) {
-
-
if (field.is_repeated())
PrintRepeatedField(proto, field, json, key);
else
@@ -513,26 +511,28 @@ namespace NProtobufJson {
template <class T, class U>
std::enable_if_t<!std::is_unsigned<T>::value, bool> ValueInRange(T value, U range) {
- return value >= -range && value <= range;
+ return value > -range && value < range;
}
template <class T, class U>
std::enable_if_t<std::is_unsigned<T>::value, bool> ValueInRange(T value, U range) {
- return value <= (std::make_unsigned_t<U>)(range);
+ return value < (std::make_unsigned_t<U>)(range);
}
template <class T>
bool TProto2JsonPrinter::NeedStringifyNumber(T value) const {
- constexpr long SAFE_INTEGER_RANGE_FLOAT = 16777216;
- constexpr long long SAFE_INTEGER_RANGE_DOUBLE = 9007199254740992;
+ constexpr long SAFE_INTEGER_RANGE_FLOAT = 1L << 24;
+ constexpr long long SAFE_INTEGER_RANGE_DOUBLE = 1LL << 53;
- switch (GetConfig().StringifyLongNumbers) {
+ switch (GetConfig().StringifyNumbers) {
case TProto2JsonConfig::StringifyLongNumbersNever:
return false;
case TProto2JsonConfig::StringifyLongNumbersForFloat:
return !ValueInRange(value, SAFE_INTEGER_RANGE_FLOAT);
case TProto2JsonConfig::StringifyLongNumbersForDouble:
return !ValueInRange(value, SAFE_INTEGER_RANGE_DOUBLE);
+ case TProto2JsonConfig::StringifyInt64Always:
+ return std::is_same_v<T, i64> || std::is_same_v<T, ui64>;
}
return false;
diff --git a/library/cpp/protobuf/json/ut/proto2json_ut.cpp b/library/cpp/protobuf/json/ut/proto2json_ut.cpp
index bf8b4994f2..b70329181d 100644
--- a/library/cpp/protobuf/json/ut/proto2json_ut.cpp
+++ b/library/cpp/protobuf/json/ut/proto2json_ut.cpp
@@ -981,46 +981,54 @@ Y_UNIT_TEST(TestMapWTF) {
UNIT_ASSERT_JSON_STRINGS_EQUAL(jsonStr.Str(), modelStr);
} // TestMapWTF
-Y_UNIT_TEST(TestStringifyLongNumbers) {
-#define TEST_SINGLE(flag, value, expectString) \
- do { \
- TFlatOptional proto; \
- proto.SetSI64(value); \
- \
- TStringStream jsonStr; \
- TProto2JsonConfig config; \
- config.SetStringifyLongNumbers(flag); \
- UNIT_ASSERT_NO_EXCEPTION(Proto2Json(proto, jsonStr, config)); \
- if (expectString) { \
- UNIT_ASSERT_EQUAL(jsonStr.Str(), "{\"SI64\":\"" #value "\"}"); \
- } else { \
- UNIT_ASSERT_EQUAL(jsonStr.Str(), "{\"SI64\":" #value "}"); \
- } \
+Y_UNIT_TEST(TestStringifyNumbers) {
+#define TEST_SINGLE(flag, field, value, expectString) \
+ do { \
+ TFlatOptional proto; \
+ proto.Set##field(value); \
+ \
+ TStringStream jsonStr; \
+ TProto2JsonConfig config; \
+ config.SetStringifyNumbers(flag); \
+ UNIT_ASSERT_NO_EXCEPTION(Proto2Json(proto, jsonStr, config)); \
+ if (expectString) { \
+ UNIT_ASSERT_EQUAL(jsonStr.Str(), "{\"" #field "\":\"" #value "\"}"); \
+ } else { \
+ UNIT_ASSERT_EQUAL(jsonStr.Str(), "{\"" #field "\":" #value "}"); \
+ } \
} while (false)
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersNever, 1, false);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersNever, 1000000000, false);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersNever, 10000000000000000, false);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersNever, -1, false);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersNever, -1000000000, false);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersNever, -10000000000000000, false);
-
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForDouble, 1, false);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForDouble, 1000000000, false);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForDouble, 10000000000000000, true);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForDouble, -1, false);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForDouble, -1000000000, false);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForDouble, -10000000000000000, true);
-
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForFloat, 1, false);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForFloat, 1000000000, true);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForFloat, 10000000000000000, true);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForFloat, -1, false);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForFloat, -1000000000, true);
- TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForFloat, -10000000000000000, true);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersNever, SI64, 1, false);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersNever, SI64, 1000000000, false);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersNever, SI64, 10000000000000000, false);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersNever, SI64, -1, false);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersNever, SI64, -1000000000, false);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersNever, SI64, -10000000000000000, false);
+
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForDouble, SI64, 1, false);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForDouble, SI64, 1000000000, false);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForDouble, SI64, 10000000000000000, true);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForDouble, SI64, -1, false);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForDouble, SI64, -1000000000, false);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForDouble, SI64, -10000000000000000, true);
+
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForFloat, SI64, 1, false);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForFloat, SI64, 1000000000, true);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForFloat, SI64, 10000000000000000, true);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForFloat, SI64, -1, false);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForFloat, SI64, -1000000000, true);
+ TEST_SINGLE(TProto2JsonConfig::StringifyLongNumbersForFloat, SI64, -10000000000000000, true);
+
+
+ TEST_SINGLE(TProto2JsonConfig::StringifyInt64Always, UI64, 1, true);
+ TEST_SINGLE(TProto2JsonConfig::StringifyInt64Always, UI32, 1000000000, false);
+ TEST_SINGLE(TProto2JsonConfig::StringifyInt64Always, UI64, 10000000000000000, true);
+ TEST_SINGLE(TProto2JsonConfig::StringifyInt64Always, SI64, -1, true);
+ TEST_SINGLE(TProto2JsonConfig::StringifyInt64Always, SI32, -1000000000, false);
+ TEST_SINGLE(TProto2JsonConfig::StringifyInt64Always, SI64, -10000000000000000, true);
#undef TEST_SINGLE
-} // TestStringifyLongNumbers
+} // TestStringifyNumbers
Y_UNIT_TEST(TestExtension) {
TExtensionField proto;