Skip to content

Commit

Permalink
Add support for Well Known Types
Browse files Browse the repository at this point in the history
  • Loading branch information
Havret committed Jun 23, 2022
1 parent 3677b77 commit ff1fba0
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 2 deletions.
22 changes: 20 additions & 2 deletions src/Protobuf.System.Text.Json/ProtobufConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
using System.Text.Json.Serialization;
using Google.Protobuf;
using Google.Protobuf.Reflection;
using Google.Protobuf.WellKnownTypes;
using Protobuf.System.Text.Json.InternalConverters;
using Type = System.Type;

namespace Protobuf.System.Text.Json;

Expand Down Expand Up @@ -167,8 +169,24 @@ private Type GetFieldType(FieldDescriptor fieldDescriptor, Dictionary<string, Ty
return typeof(bool);
case FieldType.String:
return typeof(string);
case FieldType.Message when fieldDescriptor.MessageType.ClrType != null:
return fieldDescriptor.MessageType.ClrType;
case FieldType.Message when fieldDescriptor.MessageType.ClrType is { } clrType:
if (clrType == typeof(DoubleValue))
return typeof(double?);
if (clrType == typeof(FloatValue))
return typeof(float?);
if (clrType == typeof(Int64Value))
return typeof(long?);
if (clrType == typeof(UInt64Value))
return typeof(ulong?);
if (clrType == typeof(Int32Value))
return typeof(int?);
if (clrType == typeof(UInt32Value))
return typeof(uint?);
if (clrType == typeof(BoolValue))
return typeof(bool?);
if (clrType == typeof(StringValue))
return typeof(string);
return clrType;
case FieldType.Enum when fieldDescriptor.IsRepeated:
var fieldType = propertyTypeLookup[fieldDescriptor.PropertyName];
return fieldType.GenericTypeArguments[0];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"doubleValue": null,
"floatValue": null,
"int64Value": null,
"uint64Value": null,
"int32Value": null,
"uint32Value": null,
"boolValue": null,
"stringValue": null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"doubleValue": 1.7976931348623157E+308,
"floatValue": 3.4028235E+38,
"int64Value": 9223372036854775807,
"uint64Value": 18446744073709551615,
"int32Value": 2147483647,
"uint32Value": 4294967295,
"boolValue": true,
"stringValue": "some_string_value"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using System.Text.Json;
using System.Text.Json.Protobuf.Tests;
using System.Text.Json.Serialization;
using Protobuf.System.Text.Json.Tests.Utils;
using Shouldly;
using SmartAnalyzers.ApprovalTestsExtensions;
using Xunit;

namespace Protobuf.System.Text.Json.Tests;

public class MessageWithWellKnownTypesTests
{
[Fact]
public void Should_serialize_message_with_well_known_types_when_values_are_set()
{
// Arrange
var msg = new MessageWithWellKnownTypes
{
DoubleValue = double.MaxValue,
FloatValue = float.MaxValue,
Int64Value = long.MaxValue,
Uint64Value = ulong.MaxValue,
Int32Value = int.MaxValue,
Uint32Value = uint.MaxValue,
BoolValue = true,
StringValue = "some_string_value",
};
var jsonSerializerOptions = TestHelper.CreateJsonSerializerOptions();

// Act
var serialized = JsonSerializer.Serialize(msg, jsonSerializerOptions);

// Assert
var approver = new ExplicitApprover();
approver.VerifyJson(serialized);
}

[Fact]
public void Should_serialize_message_with_well_known_types_when_values_are_not_set()
{
// Arrange
var msg = new MessageWithWellKnownTypes();
var jsonSerializerOptions = TestHelper.CreateJsonSerializerOptions();
jsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.Never;

// Act
var serialized = JsonSerializer.Serialize(msg, jsonSerializerOptions);

// Assert
var approver = new ExplicitApprover();
approver.VerifyJson(serialized);
}

[Fact]
public void Should_serialize_and_deserialize_message_with_well_known_types_when_values_are_set()
{
// Arrange
var msg = new MessageWithWellKnownTypes
{
DoubleValue = double.MaxValue,
FloatValue = float.MaxValue,
Int64Value = long.MaxValue,
Uint64Value = ulong.MaxValue,
Int32Value = int.MaxValue,
Uint32Value = uint.MaxValue,
BoolValue = true,
StringValue = "some_string_value"
};
var jsonSerializerOptions = TestHelper.CreateJsonSerializerOptions();
var serialized = JsonSerializer.Serialize(msg, jsonSerializerOptions);

// Act
var deserialized = JsonSerializer.Deserialize<MessageWithWellKnownTypes>(serialized, jsonSerializerOptions);


// Assert
deserialized.ShouldBe(msg);
}

[Fact]
public void Should_serialize_and_deserialize_message_with_well_known_types_when_values_are_not_set()
{
// Arrange
var msg = new MessageWithWellKnownTypes();
var jsonSerializerOptions = TestHelper.CreateJsonSerializerOptions();
var serialized = JsonSerializer.Serialize(msg, jsonSerializerOptions);

// Act
var deserialized = JsonSerializer.Deserialize<MessageWithWellKnownTypes>(serialized, jsonSerializerOptions);

// Assert
deserialized.ShouldBe(msg);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
syntax = "proto3";

option csharp_namespace = "System.Text.Json.Protobuf.Tests";

import "google/protobuf/wrappers.proto";

message MessageWithWellKnownTypes {
google.protobuf.DoubleValue double_value = 1;

google.protobuf.FloatValue float_value = 2;

google.protobuf.Int64Value int_64_value = 3;

google.protobuf.UInt64Value uint_64_value = 4;

google.protobuf.Int32Value int_32_Value = 5;

google.protobuf.UInt32Value uint_32_Value = 6;

google.protobuf.BoolValue bool_value = 7;

google.protobuf.StringValue string_value = 8;
}

0 comments on commit ff1fba0

Please sign in to comment.