diff options
| author | robot-piglet <[email protected]> | 2025-08-08 16:06:37 +0300 |
|---|---|---|
| committer | robot-piglet <[email protected]> | 2025-08-08 16:23:20 +0300 |
| commit | 2d176796ad5d5cc4a93658e9d5c346203b6dcadd (patch) | |
| tree | 1cdfb15922c7facc96c4d10c99f29c8ccb8463ba /library/cpp/protobuf/json/ordered_maps/json2proto_ordered.h | |
| parent | a9a64643aae00fd89fca5a63b5bdc4fc1cf5b523 (diff) | |
Intermediate changes
commit_hash:0723a1f77acac11c7a51d04edfadaeb1fe12915d
Diffstat (limited to 'library/cpp/protobuf/json/ordered_maps/json2proto_ordered.h')
| -rw-r--r-- | library/cpp/protobuf/json/ordered_maps/json2proto_ordered.h | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/library/cpp/protobuf/json/ordered_maps/json2proto_ordered.h b/library/cpp/protobuf/json/ordered_maps/json2proto_ordered.h new file mode 100644 index 00000000000..319169d8425 --- /dev/null +++ b/library/cpp/protobuf/json/ordered_maps/json2proto_ordered.h @@ -0,0 +1,244 @@ +#pragma once + +#include <library/cpp/protobuf/json/json2proto.h> + +#include <library/cpp/json/ordered_maps/json_reader_ordered.h> +#include <library/cpp/json/ordered_maps/json_value_ordered.h> + +#include <util/generic/ptr.h> +#include <util/stream/input.h> +#include <util/stream/str.h> +#include <util/stream/mem.h> + +namespace NProtobufJson::NOrderedJson { + struct TJson2ProtoConfig { + using TSelf = TJson2ProtoConfig; + using TValueVectorizer = std::function<NJson::NOrderedJson::TJsonValue::TArray(const NJson::NOrderedJson::TJsonValue& jsonValue)>; + + enum FldNameMode { + FieldNameOriginalCase = 0, // default + FieldNameLowerCase, + FieldNameUpperCase, + FieldNameCamelCase, + FieldNameSnakeCase, // ABC -> a_b_c, UserID -> user_i_d + FieldNameSnakeCaseDense // ABC -> abc, UserID -> user_id + }; + + enum EnumValueMode { + EnumCaseSensetive = 0, // default + EnumCaseInsensetive, + EnumSnakeCaseInsensitive + }; + + TSelf& SetFieldNameMode(FldNameMode mode) { + Y_ENSURE(mode == FieldNameOriginalCase || !UseJsonName, "FieldNameMode and UseJsonName are mutually exclusive"); + FieldNameMode = mode; + return *this; + } + + TSelf& SetUseJsonName(bool jsonName) { + Y_ENSURE(!jsonName || FieldNameMode == FieldNameOriginalCase, "FieldNameMode and UseJsonName are mutually exclusive"); + UseJsonName = jsonName; + return *this; + } + + TSelf& SetUseJsonEnumValue(bool jsonEnumValue) { + Y_ENSURE(!jsonEnumValue || EnumValueMode == EnumCaseSensetive, "EnumValueMode and UseJsonEnumValue are mutually exclusive"); + UseJsonEnumValue = jsonEnumValue; + return *this; + } + + TSelf& AddStringTransform(TStringTransformPtr transform) { + StringTransforms.push_back(transform); + return *this; + } + + TSelf& SetCastFromString(bool cast) { + CastFromString = cast; + return *this; + } + + TSelf& SetDoNotCastEmptyStrings(bool cast) { + DoNotCastEmptyStrings = cast; + return *this; + } + + TSelf& SetCastRobust(bool cast) { + CastRobust = cast; + return *this; + } + + TSelf& SetMapAsObject(bool mapAsObject) { + MapAsObject = mapAsObject; + return *this; + } + + TSelf& SetReplaceRepeatedFields(bool replaceRepeatedFields) { + ReplaceRepeatedFields = replaceRepeatedFields; + return *this; + } + + TSelf& SetNameGenerator(TNameGenerator callback) { + NameGenerator = callback; + return *this; + } + + TSelf& SetEnumValueMode(EnumValueMode enumValueMode) { + Y_ENSURE(!UseJsonEnumValue || enumValueMode == EnumCaseSensetive, "EnumValueMode and UseJsonEnumValue are mutually exclusive"); + EnumValueMode = enumValueMode; + return *this; + } + + TSelf& SetVectorizeScalars(bool vectorizeScalars) { + VectorizeScalars = vectorizeScalars; + return *this; + } + + TSelf& SetAllowComments(bool value) { + AllowComments = value; + return *this; + } + + TSelf& SetAllowUnknownFields(bool value) { + AllowUnknownFields = value; + return *this; + } + + TSelf& SetAllowString2TimeConversion(bool value) { + AllowString2TimeConversion = value; + return *this; + } + + TSelf& SetUnknownFieldsCollector(TSimpleSharedPtr<IUnknownFieldsCollector> value) { + UnknownFieldsCollector = std::move(value); + return *this; + } + + FldNameMode FieldNameMode = FieldNameOriginalCase; + bool AllowUnknownFields = true; + + /// Use 'json_name' protobuf option for field name, mutually exclusive + /// with FieldNameMode. + bool UseJsonName = false; + + /// Use 'json_enum_value' protobuf option for enum value, mutually exclusive + /// with EnumValueMode + bool UseJsonEnumValue = false; + + /// Transforms will be applied only to string values (== protobuf fields of string / bytes type). + TVector<TStringTransformPtr> StringTransforms; + + /// Cast string json values to protobuf field type + bool CastFromString = false; + /// Skip empty strings, instead casting from string into scalar types. + /// I.e. empty string like default value for scalar types. + bool DoNotCastEmptyStrings = false; + /// Cast all json values to protobuf field types + bool CastRobust = false; + + /// Consider map to be an object, otherwise consider it to be an array of key/value objects + bool MapAsObject = false; + + /// Throw exception if there is no required fields in json object. + bool CheckRequiredFields = true; + + /// Replace repeated fields content during merging + bool ReplaceRepeatedFields = false; + + /// Custom field names generator. + TNameGenerator NameGenerator = {}; + + /// Enum value parsing mode. + EnumValueMode EnumValueMode = EnumCaseSensetive; + + /// Append scalars to repeated fields + bool VectorizeScalars = false; + + /// Custom spliter non array value to repeated fields. + TValueVectorizer ValueVectorizer; + + /// Allow js-style comments (both // and /**/) + bool AllowComments = false; + + /// Allow nonstandard conversions, e.g. google.protobuf.Duration from String + bool AllowString2TimeConversion = false; + + /// Stores information about unknown fields + TSimpleSharedPtr<IUnknownFieldsCollector> UnknownFieldsCollector = nullptr; + }; + + /// @throw yexception + void MergeJson2Proto(const NJson::NOrderedJson::TJsonValue& json, google::protobuf::Message& proto, + const TJson2ProtoConfig& config = TJson2ProtoConfig()); + + /// @throw yexception + void MergeJson2Proto(const TStringBuf& json, google::protobuf::Message& proto, + const TJson2ProtoConfig& config = TJson2ProtoConfig()); + + /// @throw yexception + inline void MergeJson2Proto(const TString& json, google::protobuf::Message& proto, + const TJson2ProtoConfig& config = TJson2ProtoConfig()) { + MergeJson2Proto(TStringBuf(json), proto, config); + } + + /// @throw yexception + void Json2Proto(const NJson::NOrderedJson::TJsonValue& json, google::protobuf::Message& proto, + const TJson2ProtoConfig& config = TJson2ProtoConfig()); + + /// @throw yexception + void Json2Proto(const TStringBuf& json, google::protobuf::Message& proto, + const TJson2ProtoConfig& config = TJson2ProtoConfig()); + + /// @throw yexception + inline void Json2Proto(const TString& json, google::protobuf::Message& proto, + const TJson2ProtoConfig& config = TJson2ProtoConfig()) { + Json2Proto(TStringBuf(json), proto, config); + } + + /// @throw yexception + inline void Json2Proto(IInputStream& in, google::protobuf::Message& proto, + const TJson2ProtoConfig& config = TJson2ProtoConfig()) { + Json2Proto(TStringBuf(in.ReadAll()), proto, config); + } + + /// @throw yexception + template <typename T> + T Json2Proto(IInputStream& in, const NJson::NOrderedJson::TJsonReaderConfig& readerConfig, + const TJson2ProtoConfig& config = TJson2ProtoConfig()) { + NJson::NOrderedJson::TJsonValue jsonValue; + NJson::NOrderedJson::ReadJsonTree(&in, &readerConfig, &jsonValue, true); + T protoValue; + Json2Proto(jsonValue, protoValue, config); + return protoValue; + } + + /// @throw yexception + template <typename T> + T Json2Proto(IInputStream& in, const TJson2ProtoConfig& config = TJson2ProtoConfig()) { + // NOTE: TJson2ProtoConfig.AllowComments=true doesn't work, when using TJsonReaderConfig + NJson::NOrderedJson::TJsonReaderConfig readerConfig; + readerConfig.DontValidateUtf8 = true; + return Json2Proto<T>(in, readerConfig, config); + } + + /// @throw yexception + template <typename T> + T Json2Proto(const TString& value, const TJson2ProtoConfig& config = TJson2ProtoConfig()) { + return Json2Proto<T>(TStringBuf(value), config); + } + + /// @throw yexception + template <typename T> + T Json2Proto(const TStringBuf& value, const TJson2ProtoConfig& config = TJson2ProtoConfig()) { + T protoValue; + Json2Proto(value, protoValue, config); + return protoValue; + } + + /// @throw yexception + template <typename T> + T Json2Proto(const char* ptr, const TJson2ProtoConfig& config = TJson2ProtoConfig()) { + return Json2Proto<T>(TStringBuf(ptr), config); + } + +} |
