Эх сурвалжийг харах

Support (and test) numeric enum parsing in JSON

Jon Skeet 9 жил өмнө
parent
commit
730c38ad8c

+ 20 - 0
csharp/src/Google.Protobuf.Test/JsonParserTest.cs

@@ -821,6 +821,26 @@ namespace Google.Protobuf
             Assert.Throws<InvalidProtocolBufferException>(() => parser63.Parse<TestRecursiveMessage>(data64));
         }
 
+        [Test]
+        [TestCase("\"FOREIGN_BAR\"")]
+        [TestCase("5")]
+        public void EnumValid(string value)
+        {
+            string json = "{ \"singleForeignEnum\": " + value + " }";
+            var parsed = TestAllTypes.Parser.ParseJson(json);
+            Assert.AreEqual(new TestAllTypes { SingleForeignEnum = ForeignEnum.FOREIGN_BAR }, parsed);
+        }
+
+        [Test]
+        [TestCase("\"NOT_A_VALID_VALUE\"")]
+        [TestCase("100")]
+        [TestCase("5.5")]
+        public void Enum_Invalid(string value)
+        {
+            string json = "{ \"singleForeignEnum\": " + value + " }";
+            Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+        }
+
         /// <summary>
         /// Various tests use strings which have quotes round them for parsing or as the result
         /// of formatting, but without those quotes being specified in the tests (for the sake of readability).

+ 9 - 0
csharp/src/Google.Protobuf/JsonParser.cs

@@ -608,6 +608,15 @@ namespace Google.Protobuf
                                 throw new InvalidProtocolBufferException($"Value out of range: {value}");
                             }
                             return (float) value;
+                        case FieldType.Enum:
+                            CheckInteger(value);
+                            var enumValue = field.EnumType.FindValueByNumber((int) value);
+                            if (enumValue == null)
+                            {
+                                throw new InvalidProtocolBufferException($"Invalid enum value: {value} for enum type: {field.EnumType.FullName}");
+                            }
+                            // Just return it as an int, and let the CLR convert it.
+                            return enumValue.Number;
                         default:
                             throw new InvalidProtocolBufferException($"Unsupported conversion from JSON number for field type {field.FieldType}");
                     }