diff options
author | dddlatyshev <dddlatyshev@yandex-team.com> | 2023-02-22 19:30:31 +0300 |
---|---|---|
committer | dddlatyshev <dddlatyshev@yandex-team.com> | 2023-02-22 19:30:31 +0300 |
commit | e335b244b0805b9744c35500685750135c97bd8f (patch) | |
tree | a9492ee15bafec49139dbd31234defc4da8ba4c7 /library/cpp | |
parent | d6db0fa7fd05eea98ca692ecc6bd29c2b08700c3 (diff) | |
download | ydb-e335b244b0805b9744c35500685750135c97bd8f.tar.gz |
Add StringifyInt64Always mode
Diffstat (limited to 'library/cpp')
-rw-r--r-- | library/cpp/protobuf/json/config.h | 9 | ||||
-rw-r--r-- | library/cpp/protobuf/json/proto2json_printer.cpp | 14 | ||||
-rw-r--r-- | library/cpp/protobuf/json/ut/proto2json_ut.cpp | 80 |
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; |