diff --git a/src/Protobuf.System.Text.Json/FieldTypeResolver.cs b/src/Protobuf.System.Text.Json/FieldTypeResolver.cs index c0f70fc..d55b13e 100644 --- a/src/Protobuf.System.Text.Json/FieldTypeResolver.cs +++ b/src/Protobuf.System.Text.Json/FieldTypeResolver.cs @@ -1,3 +1,4 @@ +using Google.Protobuf; using Google.Protobuf.Reflection; using Google.Protobuf.WellKnownTypes; using Type = System.Type; @@ -32,6 +33,8 @@ public static Type ResolverFieldType(FieldDescriptor fieldDescriptor, Dictionary return typeof(bool); case FieldType.String: return typeof(string); + case FieldType.Bytes: + return typeof(ByteString); case FieldType.Message when fieldDescriptor.MessageType.ClrType is { } clrType: if (clrType == typeof(DoubleValue)) return typeof(double?); @@ -58,7 +61,7 @@ public static Type ResolverFieldType(FieldDescriptor fieldDescriptor, Dictionary return propertyTypeLookup[fieldDescriptor.PropertyName]; default: throw new ArgumentOutOfRangeException(nameof(fieldDescriptor), - $"FieldType: '{fieldDescriptor}' is not supported."); + $"FieldType: '{fieldDescriptor.FieldType}' is not supported."); } } } \ No newline at end of file diff --git a/src/Protobuf.System.Text.Json/JsonSerializerOptionsExtensions.cs b/src/Protobuf.System.Text.Json/JsonSerializerOptionsExtensions.cs index c36b0c4..fec419c 100644 --- a/src/Protobuf.System.Text.Json/JsonSerializerOptionsExtensions.cs +++ b/src/Protobuf.System.Text.Json/JsonSerializerOptionsExtensions.cs @@ -23,6 +23,7 @@ public static void AddProtobufSupport(this JsonSerializerOptions options, Action { options.Converters.Add(new TimestampConverter()); } + options.Converters.Add(new ByteStringConverter()); options.Converters.Add(new ProtobufJsonConverterFactory(jsonProtobufSerializerOptions)); } diff --git a/src/Protobuf.System.Text.Json/WellKnownTypesConverters/ByteStringConverter.cs b/src/Protobuf.System.Text.Json/WellKnownTypesConverters/ByteStringConverter.cs new file mode 100644 index 0000000..c3479a9 --- /dev/null +++ b/src/Protobuf.System.Text.Json/WellKnownTypesConverters/ByteStringConverter.cs @@ -0,0 +1,26 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using Google.Protobuf; + +namespace Protobuf.System.Text.Json.WellKnownTypesConverters; + +internal class ByteStringConverter : JsonConverter +{ + public override ByteString? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.GetString() is { } base64String) + { + return ByteString.FromBase64(base64String); + } + + return null; + } + + public override void Write(Utf8JsonWriter writer, ByteString? value, JsonSerializerOptions options) + { + if (value != null) + { + writer.WriteStringValue(value.ToBase64()); + } + } +} \ No newline at end of file diff --git a/test/Protobuf.System.Text.Json.Tests/DefaultIgnoreConditionTests.Should_not_ignore_default_non_nullable_properties_when_DefaultIgnoreCondition_set_to_WhenWritingNull.approved.json b/test/Protobuf.System.Text.Json.Tests/DefaultIgnoreConditionTests.Should_not_ignore_default_non_nullable_properties_when_DefaultIgnoreCondition_set_to_WhenWritingNull.approved.json index c263be5..87c6505 100644 --- a/test/Protobuf.System.Text.Json.Tests/DefaultIgnoreConditionTests.Should_not_ignore_default_non_nullable_properties_when_DefaultIgnoreCondition_set_to_WhenWritingNull.approved.json +++ b/test/Protobuf.System.Text.Json.Tests/DefaultIgnoreConditionTests.Should_not_ignore_default_non_nullable_properties_when_DefaultIgnoreCondition_set_to_WhenWritingNull.approved.json @@ -12,5 +12,6 @@ "sfixed32Property": 0, "sfixed64Property": 0, "boolProperty": false, - "stringProperty": "" + "stringProperty": "", + "bytesProperty": "" } \ No newline at end of file diff --git a/test/Protobuf.System.Text.Json.Tests/DefaultIgnoreConditionTests.Should_not_ignore_default_properties_when_DefaultIgnoreCondition_set_to_Never.approved.json b/test/Protobuf.System.Text.Json.Tests/DefaultIgnoreConditionTests.Should_not_ignore_default_properties_when_DefaultIgnoreCondition_set_to_Never.approved.json index c263be5..87c6505 100644 --- a/test/Protobuf.System.Text.Json.Tests/DefaultIgnoreConditionTests.Should_not_ignore_default_properties_when_DefaultIgnoreCondition_set_to_Never.approved.json +++ b/test/Protobuf.System.Text.Json.Tests/DefaultIgnoreConditionTests.Should_not_ignore_default_properties_when_DefaultIgnoreCondition_set_to_Never.approved.json @@ -12,5 +12,6 @@ "sfixed32Property": 0, "sfixed64Property": 0, "boolProperty": false, - "stringProperty": "" + "stringProperty": "", + "bytesProperty": "" } \ No newline at end of file diff --git a/test/Protobuf.System.Text.Json.Tests/JsonNamingPolicyTests.Should_ignore_PropertyNamingPolicy_when_UseProtobufJsonNames_set_to_true.approved.json b/test/Protobuf.System.Text.Json.Tests/JsonNamingPolicyTests.Should_ignore_PropertyNamingPolicy_when_UseProtobufJsonNames_set_to_true.approved.json index 9a88710..1283b7d 100644 --- a/test/Protobuf.System.Text.Json.Tests/JsonNamingPolicyTests.Should_ignore_PropertyNamingPolicy_when_UseProtobufJsonNames_set_to_true.approved.json +++ b/test/Protobuf.System.Text.Json.Tests/JsonNamingPolicyTests.Should_ignore_PropertyNamingPolicy_when_UseProtobufJsonNames_set_to_true.approved.json @@ -12,5 +12,6 @@ "sfixed32Property": 0, "sfixed64Property": 0, "boolProperty": false, - "stringProperty": "" + "stringProperty": "", + "bytesProperty": "" } \ No newline at end of file diff --git a/test/Protobuf.System.Text.Json.Tests/JsonNamingPolicyTests.Should_serialize_message_with_primitive_types.approved.json b/test/Protobuf.System.Text.Json.Tests/JsonNamingPolicyTests.Should_serialize_message_with_primitive_types.approved.json index 488c716..30351d3 100644 --- a/test/Protobuf.System.Text.Json.Tests/JsonNamingPolicyTests.Should_serialize_message_with_primitive_types.approved.json +++ b/test/Protobuf.System.Text.Json.Tests/JsonNamingPolicyTests.Should_serialize_message_with_primitive_types.approved.json @@ -12,5 +12,6 @@ "sfixed32property": 0, "sfixed64property": 0, "boolproperty": false, - "stringproperty": "" + "stringproperty": "", + "bytesproperty": "" } \ No newline at end of file diff --git a/test/Protobuf.System.Text.Json.Tests/MessageWithMapsTests.Should_serialize_message_with_map_field.approved.json b/test/Protobuf.System.Text.Json.Tests/MessageWithMapsTests.Should_serialize_message_with_map_field.approved.json index 34e6706..449aff5 100644 --- a/test/Protobuf.System.Text.Json.Tests/MessageWithMapsTests.Should_serialize_message_with_map_field.approved.json +++ b/test/Protobuf.System.Text.Json.Tests/MessageWithMapsTests.Should_serialize_message_with_map_field.approved.json @@ -8,5 +8,8 @@ "a": 1 } } + }, + "mapStringToBytesType": { + "string_key": "YWJj" } } \ No newline at end of file diff --git a/test/Protobuf.System.Text.Json.Tests/MessageWithMapsTests.cs b/test/Protobuf.System.Text.Json.Tests/MessageWithMapsTests.cs index 04d6ab5..3fbb86b 100644 --- a/test/Protobuf.System.Text.Json.Tests/MessageWithMapsTests.cs +++ b/test/Protobuf.System.Text.Json.Tests/MessageWithMapsTests.cs @@ -1,5 +1,6 @@ using System.Text.Json; using System.Text.Json.Protobuf.Tests; +using Google.Protobuf; using Protobuf.System.Text.Json.Tests.Utils; using Shouldly; using SmartAnalyzers.ApprovalTestsExtensions; @@ -22,7 +23,8 @@ public void Should_serialize_message_with_map_field() { MapStringToInt = {["a"] = 1} } - } + }, + MapStringToBytesType = { ["string_key"] = ByteString.CopyFromUtf8("abc") } }; var jsonSerializerOptions = TestHelper.CreateJsonSerializerOptions(); @@ -47,7 +49,8 @@ public void Should_deserialize_message_with_map_field() { MapStringToInt = {["a"] = 1} } - } + }, + MapStringToBytesType = { ["string_key"] = ByteString.CopyFromUtf8("abc") } }; var jsonSerializerOptions = TestHelper.CreateJsonSerializerOptions(); diff --git a/test/Protobuf.System.Text.Json.Tests/Protos/message_with_maps.proto b/test/Protobuf.System.Text.Json.Tests/Protos/message_with_maps.proto index 1d42802..a71527d 100644 --- a/test/Protobuf.System.Text.Json.Tests/Protos/message_with_maps.proto +++ b/test/Protobuf.System.Text.Json.Tests/Protos/message_with_maps.proto @@ -5,6 +5,7 @@ option csharp_namespace = "System.Text.Json.Protobuf.Tests"; message MessageWithMaps { map map_int_to_string = 1; map map_string_to_complex_type = 2; + map map_string_to_bytes_type = 3; } message NestedMessageAsKey { diff --git a/test/Protobuf.System.Text.Json.Tests/Protos/simple_message.proto b/test/Protobuf.System.Text.Json.Tests/Protos/simple_message.proto index 1719c6c..2805a7e 100644 --- a/test/Protobuf.System.Text.Json.Tests/Protos/simple_message.proto +++ b/test/Protobuf.System.Text.Json.Tests/Protos/simple_message.proto @@ -31,6 +31,5 @@ message SimpleMessage { string string_property = 14; - // TODO: Support bytes property - // bytes bytes_property = 15; + bytes bytes_property = 15; } \ No newline at end of file diff --git a/test/Protobuf.System.Text.Json.Tests/SimpleMessageTests.Should_serialize_message_with_primitive_types.approved.json b/test/Protobuf.System.Text.Json.Tests/SimpleMessageTests.Should_serialize_message_with_primitive_types.approved.json index b0c1fb0..bab7abd 100644 --- a/test/Protobuf.System.Text.Json.Tests/SimpleMessageTests.Should_serialize_message_with_primitive_types.approved.json +++ b/test/Protobuf.System.Text.Json.Tests/SimpleMessageTests.Should_serialize_message_with_primitive_types.approved.json @@ -12,5 +12,6 @@ "sfixed32Property": 9, "sfixed64Property": 10, "boolProperty": true, - "stringProperty": "hello" + "stringProperty": "hello", + "bytesProperty": "YWJj" } \ No newline at end of file diff --git a/test/Protobuf.System.Text.Json.Tests/SimpleMessageTests.cs b/test/Protobuf.System.Text.Json.Tests/SimpleMessageTests.cs index 2f69e24..6899cf9 100644 --- a/test/Protobuf.System.Text.Json.Tests/SimpleMessageTests.cs +++ b/test/Protobuf.System.Text.Json.Tests/SimpleMessageTests.cs @@ -1,5 +1,6 @@ using System.Text.Json; using System.Text.Json.Protobuf.Tests; +using Google.Protobuf; using Protobuf.System.Text.Json.Tests.Utils; using Shouldly; using SmartAnalyzers.ApprovalTestsExtensions; @@ -28,9 +29,8 @@ public void Should_serialize_message_with_primitive_types() Sfixed32Property = 9, Sfixed64Property = 10, BoolProperty = true, - StringProperty = "hello" - // TODO: Support bytes property - // BytesProperty = ByteString.CopyFromUtf8("abc") + StringProperty = "hello", + BytesProperty = ByteString.CopyFromUtf8("abc") }; var jsonSerializerOptions = TestHelper.CreateJsonSerializerOptions(); @@ -61,9 +61,8 @@ public void Should_deserialize_message_with_primitive_types() Sfixed32Property = 9, Sfixed64Property = 10, BoolProperty = true, - StringProperty = "hello" - // TODO: Support bytes property - // BytesProperty = ByteString.CopyFromUtf8("abc") + StringProperty = "hello", + BytesProperty = ByteString.CopyFromUtf8("abc") }; var jsonSerializerOptions = TestHelper.CreateJsonSerializerOptions();