Преглед на файлове

Merge pull request #1707 from jskeet/format-value

Expose JsonFormatter.WriteValue.
Jan Tattermusch преди 9 години
родител
ревизия
6f67be6f37
променени са 2 файла, в които са добавени 58 реда и са изтрити 25 реда
  1. 47 0
      csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
  2. 11 25
      csharp/src/Google.Protobuf/JsonFormatter.cs

+ 47 - 0
csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs

@@ -38,6 +38,8 @@ using Google.Protobuf.WellKnownTypes;
 using Google.Protobuf.Reflection;
 
 using static Google.Protobuf.JsonParserTest; // For WrapInQuotes
+using System.IO;
+using Google.Protobuf.Collections;
 
 namespace Google.Protobuf
 {
@@ -528,6 +530,51 @@ namespace Google.Protobuf
             Assert.AreEqual(expectedJson, JsonFormatter.Default.Format(populated));
         }
 
+        // Sanity tests for WriteValue. Not particularly comprehensive, as it's all covered above already,
+        // as FormatMessage uses WriteValue.
+
+        [TestCase(null, "null")]
+        [TestCase(1, "1")]
+        [TestCase(1L, "'1'")]
+        [TestCase(0.5f, "0.5")]
+        [TestCase(0.5d, "0.5")]
+        [TestCase("text", "'text'")]
+        [TestCase("x\ny", @"'x\ny'")]
+        [TestCase(ForeignEnum.ForeignBar, "'FOREIGN_BAR'")]
+        public void WriteValue_Constant(object value, string expectedJson)
+        {
+            AssertWriteValue(value, expectedJson);
+        }
+
+        [Test]
+        public void WriteValue_Timestamp()
+        {
+            var value = new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp();
+            AssertWriteValue(value, "'1673-06-19T12:34:56Z'");
+        }
+
+        [Test]
+        public void WriteValue_Message()
+        {
+            var value = new TestAllTypes { SingleInt32 = 100, SingleInt64 = 3210987654321L };
+            AssertWriteValue(value, "{ 'singleInt32': 100, 'singleInt64': '3210987654321' }");
+        }
+
+        [Test]
+        public void WriteValue_List()
+        {
+            var value = new RepeatedField<int> { 1, 2, 3 };
+            AssertWriteValue(value, "[ 1, 2, 3 ]");
+        }
+
+        private static void AssertWriteValue(object value, string expectedJson)
+        {
+            var writer = new StringWriter();
+            JsonFormatter.Default.WriteValue(writer, value);
+            string actual = writer.ToString();
+            AssertJson(expectedJson, actual);
+        }
+
         /// <summary>
         /// Checks that the actual JSON is the same as the expected JSON - but after replacing
         /// all apostrophes in the expected JSON with double quotes. This basically makes the tests easier

+ 11 - 25
csharp/src/Google.Protobuf/JsonFormatter.cs

@@ -377,8 +377,16 @@ namespace Google.Protobuf
                     throw new ArgumentException("Invalid field type");
             }
         }
-        
-        private void WriteValue(TextWriter writer, object value)
+
+        /// <summary>
+        /// Writes a single value to the given writer as JSON. Only types understood by
+        /// Protocol Buffers can be written in this way. This method is only exposed for
+        /// advanced use cases; most users should be using <see cref="Format(IMessage)"/>
+        /// or <see cref="Format(IMessage, TextWriter)"/>.
+        /// </summary>
+        /// <param name="writer">The writer to write the value to. Must not be null.</param>
+        /// <param name="value">The value to write. May be null.</param>
+        public void WriteValue(TextWriter writer, object value)
         {
             if (value == null)
             {
@@ -447,15 +455,7 @@ namespace Google.Protobuf
             }
             else if (value is IMessage)
             {
-                IMessage message = (IMessage) value;
-                if (message.Descriptor.IsWellKnownType)
-                {
-                    WriteWellKnownTypeValue(writer, message.Descriptor, value);
-                }
-                else
-                {
-                    WriteMessage(writer, (IMessage)value);
-                }
+                Format((IMessage)value, writer);
             }
             else
             {
@@ -723,20 +723,6 @@ namespace Google.Protobuf
             writer.Write(first ? "}" : " }");
         }
 
-        /// <summary>
-        /// Returns whether or not a singular value can be represented in JSON.
-        /// Currently only relevant for enums, where unknown values can't be represented.
-        /// For repeated/map fields, this always returns true.
-        /// </summary>
-        private bool CanWriteSingleValue(object value)
-        {
-            if (value is System.Enum)
-            {
-                return System.Enum.IsDefined(value.GetType(), value);
-            }
-            return true;
-        }
-
         /// <summary>
         /// Writes a string (including leading and trailing double quotes) to a builder, escaping as required.
         /// </summary>