From 0e30de3d6b99f79efc9ddafa9e60916a54524353 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Mon, 3 Aug 2015 11:43:07 +0100 Subject: JSON formatting for FieldMask --- .../src/Google.Protobuf.Test/JsonFormatterTest.cs | 18 ++++++++++++++++++ csharp/src/Google.Protobuf/JsonFormatter.cs | 22 +++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) (limited to 'csharp/src') diff --git a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs index f6e6488f..ecd7f46b 100644 --- a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs +++ b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs @@ -388,6 +388,24 @@ namespace Google.Protobuf AssertJson("{ 'a': null, 'b': false, 'c': 10.5, 'd': 'text', 'e': [ 't1', 5 ], 'f': { 'nested': 'value' } }", message.ToString()); } + [Test] + public void FieldMaskStandalone() + { + var fieldMask = new FieldMask { Paths = { "", "single", "with_underscore", "nested.field.name", "nested..double_dot" } }; + Assert.AreEqual(",single,withUnderscore,nested.field.name,nested..doubleDot", fieldMask.ToString()); + + // Invalid, but we shouldn't create broken JSON... + fieldMask = new FieldMask { Paths = { "x\\y" } }; + Assert.AreEqual(@"x\\y", fieldMask.ToString()); + } + + [Test] + public void FieldMaskField() + { + var message = new TestWellKnownTypes { FieldMaskField = new FieldMask { Paths = { "user.display_name", "photo" } } }; + AssertJson("{ 'fieldMaskField': 'user.displayName,photo' }", JsonFormatter.Default.Format(message)); + } + /// /// 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 diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs index 3b25beb6..999e106c 100644 --- a/csharp/src/Google.Protobuf/JsonFormatter.cs +++ b/csharp/src/Google.Protobuf/JsonFormatter.cs @@ -36,6 +36,7 @@ using System.Globalization; using System.Text; using Google.Protobuf.Reflection; using Google.Protobuf.WellKnownTypes; +using System.Linq; namespace Google.Protobuf { @@ -402,6 +403,11 @@ namespace Google.Protobuf MaybeWrapInString(builder, value, WriteDuration, inField); return; } + if (descriptor.FullName == FieldMask.Descriptor.FullName) + { + MaybeWrapInString(builder, value, WriteFieldMask, inField); + return; + } if (descriptor.FullName == Struct.Descriptor.FullName) { WriteStruct(builder, (IMessage) value); @@ -479,6 +485,12 @@ namespace Google.Protobuf builder.Append('s'); } + private void WriteFieldMask(StringBuilder builder, IMessage value) + { + IList paths = (IList) value.Descriptor.Fields[FieldMask.PathsFieldNumber].Accessor.GetValue(value); + AppendEscapedString(builder, string.Join(",", paths.Cast().Select(ToCamelCase))); + } + /// /// Appends a number of nanoseconds to a StringBuilder. Either 0 digits are added (in which /// case no "." is appended), or 3 6 or 9 digits. @@ -654,6 +666,15 @@ namespace Google.Protobuf private void WriteString(StringBuilder builder, string text) { builder.Append('"'); + AppendEscapedString(builder, text); + builder.Append('"'); + } + + /// + /// Appends the given text to the string builder, escaping as required. + /// + private void AppendEscapedString(StringBuilder builder, string text) + { for (int i = 0; i < text.Length; i++) { char c = text[i]; @@ -713,7 +734,6 @@ namespace Google.Protobuf break; } } - builder.Append('"'); } private const string Hex = "0123456789abcdef"; -- cgit v1.2.3