Skip to content

Commit d1e1627

Browse files
authored
Serialize fractional numbers with trailing decimal point and value (#3660)
This commit updates - the DoubleToStringConverter from utf8json to always emit a trailing decimal point and trailing decimal value when serializing floating point numbers to JSON. - the DecimalFormatter from utf8json to always emit a trailing decimal point and trailing decimal value when serializing floating point numbers to JSON. Update unit tests to reflect this change Fixes #3657
1 parent faf6098 commit d1e1627

File tree

14 files changed

+95
-70
lines changed

14 files changed

+95
-70
lines changed

src/Elasticsearch.Net/Utf8Json/Formatters/StandardClassLibraryFormatters.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,14 +307,16 @@ public DecimalFormatter(bool serializeAsString)
307307

308308
public void Serialize(ref JsonWriter writer, decimal value, IJsonFormatterResolver formatterResolver)
309309
{
310+
// always include decimal point and at least one decimal place
311+
var s = value.ToString("0.0###########################", CultureInfo.InvariantCulture);
310312
if (serializeAsString)
311313
{
312-
writer.WriteString(value.ToString(CultureInfo.InvariantCulture));
314+
writer.WriteString(s);
313315
}
314316
else
315317
{
316318
// write as number format.
317-
writer.WriteRaw(StringEncoding.UTF8.GetBytes(value.ToString(CultureInfo.InvariantCulture)));
319+
writer.WriteRaw(StringEncoding.UTF8.GetBytes(s));
318320
}
319321
}
320322

src/Elasticsearch.Net/Utf8Json/Internal/DoubleConversion/DoubleToStringConverter.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ enum DtoaMode
185185
// PRECISION
186186
}
187187

188+
[Flags]
188189
enum Flags
189190
{
190191
NO_FLAGS = 0,
@@ -214,7 +215,7 @@ enum Flags
214215
//const int max_leading_padding_zeroes_in_precision_mode_;
215216
//const int max_trailing_padding_zeroes_in_precision_mode_;
216217

217-
static readonly Flags flags_ = Flags.UNIQUE_ZERO | Flags.EMIT_POSITIVE_EXPONENT_SIGN;
218+
static readonly Flags flags_ = Flags.UNIQUE_ZERO | Flags.EMIT_POSITIVE_EXPONENT_SIGN | Flags.EMIT_TRAILING_DECIMAL_POINT | Flags.EMIT_TRAILING_ZERO_AFTER_POINT;
218219
static readonly char exponent_character_ = 'E';
219220
static readonly int decimal_in_shortest_low_ = -4; // C# ToString("G")
220221
static readonly int decimal_in_shortest_high_ = 15;// C# ToString("G")

src/Elasticsearch.Net/Utf8Json/Internal/DoubleConversion/StringToDoubleConverter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ public static float ToSingle(byte[] buffer, int offset, out int readCount)
160160
// port
161161
internal static partial class StringToDoubleConverter
162162
{
163+
[Flags]
163164
enum Flags
164165
{
165166
NO_FLAGS = 0,

src/Elasticsearch.Net/Utf8Json/JsonSerializer.cs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,7 @@ public static T Deserialize<T>(Stream stream, IJsonFormatterResolver resolver)
285285
var ms = stream as MemoryStream;
286286
if (ms != null)
287287
{
288-
ArraySegment<byte> buf2;
289-
if (ms.TryGetBuffer(out buf2))
288+
if (ms.TryGetBuffer(out var buf2))
290289
{
291290
// when token is number, can not use from pool(can not find end line).
292291
var token = new JsonReader(buf2.Array, buf2.Offset).GetCurrentJsonToken();
@@ -367,19 +366,16 @@ public static async System.Threading.Tasks.Task<T> DeserializeAsync<T>(Stream st
367366

368367
#endif
369368

370-
public static string PrettyPrint(byte[] json)
371-
{
372-
return PrettyPrint(json, 0);
373-
}
369+
public static string PrettyPrint(byte[] json) => PrettyPrint(json, 0);
374370

375-
public static string PrettyPrint(byte[] json, int offset)
371+
public static string PrettyPrint(byte[] json, int offset)
376372
{
377373
var reader = new JsonReader(json, offset);
378374
var buffer = MemoryPool.Rent();
379375
try
380376
{
381377
var writer = new JsonWriter(buffer);
382-
WritePrittyPrint(ref reader, ref writer, 0);
378+
WritePrettyPrint(ref reader, ref writer, 0);
383379
return writer.ToString();
384380
}
385381
finally
@@ -396,7 +392,7 @@ public static string PrettyPrint(string json)
396392
try
397393
{
398394
var writer = new JsonWriter(buffer);
399-
WritePrittyPrint(ref reader, ref writer, 0);
395+
WritePrettyPrint(ref reader, ref writer, 0);
400396
return writer.ToString();
401397
}
402398
finally
@@ -418,7 +414,7 @@ public static byte[] PrettyPrintByteArray(byte[] json, int offset)
418414
try
419415
{
420416
var writer = new JsonWriter(buffer);
421-
WritePrittyPrint(ref reader, ref writer, 0);
417+
WritePrettyPrint(ref reader, ref writer, 0);
422418
return writer.ToUtf8ByteArray();
423419
}
424420
finally
@@ -434,7 +430,7 @@ public static byte[] PrettyPrintByteArray(string json)
434430
try
435431
{
436432
var writer = new JsonWriter(buffer);
437-
WritePrittyPrint(ref reader, ref writer, 0);
433+
WritePrettyPrint(ref reader, ref writer, 0);
438434
return writer.ToUtf8ByteArray();
439435
}
440436
finally
@@ -446,7 +442,7 @@ public static byte[] PrettyPrintByteArray(string json)
446442
static readonly byte[][] indent = Enumerable.Range(0, 100).Select(x => Encoding.UTF8.GetBytes(new string(' ', x * 2))).ToArray();
447443
static readonly byte[] newLine = Encoding.UTF8.GetBytes(Environment.NewLine);
448444

449-
static void WritePrittyPrint(ref JsonReader reader, ref JsonWriter writer, int depth)
445+
static void WritePrettyPrint(ref JsonReader reader, ref JsonWriter writer, int depth)
450446
{
451447
var token = reader.GetCurrentJsonToken();
452448
switch (token)
@@ -466,7 +462,7 @@ static void WritePrittyPrint(ref JsonReader reader, ref JsonWriter writer, int d
466462
writer.WriteRaw(indent[depth + 1]);
467463
writer.WritePropertyName(reader.ReadPropertyName());
468464
writer.WriteRaw((byte)' ');
469-
WritePrittyPrint(ref reader, ref writer, depth + 1);
465+
WritePrettyPrint(ref reader, ref writer, depth + 1);
470466
}
471467
writer.WriteRaw(newLine);
472468
writer.WriteRaw(indent[depth]);
@@ -486,7 +482,7 @@ static void WritePrittyPrint(ref JsonReader reader, ref JsonWriter writer, int d
486482
writer.WriteRaw(newLine);
487483
}
488484
writer.WriteRaw(indent[depth + 1]);
489-
WritePrittyPrint(ref reader, ref writer, depth + 1);
485+
WritePrettyPrint(ref reader, ref writer, depth + 1);
490486
}
491487
writer.WriteRaw(newLine);
492488
writer.WriteRaw(indent[depth]);

src/Nest/Search/Suggesters/TermSuggester/TermSuggester.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ public interface ITermSuggester : ISuggester
3838
StringDistance? StringDistance { get; set; }
3939

4040
[DataMember(Name = "suggest_mode")]
41-
4241
SuggestMode? SuggestMode { get; set; }
4342

4443
[IgnoreDataMember]

src/Tests/Tests.Core/Serialization/SerializationTester.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ private JsonSerializerSettings ExpectedJsonSerializerSettings(bool preserveNullI
237237
ContractResolver = new DefaultContractResolver { NamingStrategy = new DefaultNamingStrategy() },
238238
NullValueHandling = preserveNullInExpected ? NullValueHandling.Include : NullValueHandling.Ignore,
239239
//copied here because anonymyzing geocoordinates is too tedious
240-
Converters = new List<JsonConverter> { new TestGeoCoordinateJsonConverter(), new Utf8JsonDecimalConverter() }
240+
Converters = new List<JsonConverter> { new TestGeoCoordinateJsonConverter() }
241241
};
242242
}
243243
}

src/Tests/Tests.Core/Serialization/Utf8JsonDecimalConverter.cs

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/Tests/Tests/Aggregations/Matrix/MatrixStats/MatrixStatsAggregationUsageTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ public MatrixStatsAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usage)
2828
fields = new[] { "numberOfCommits", "numberOfContributors" },
2929
missing = new
3030
{
31-
numberOfCommits = 0,
32-
numberOfContributors = 1
31+
numberOfCommits = 0.0,
32+
numberOfContributors = 1.0
3333
},
3434
mode = "median"
3535
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
using Elastic.Xunit.XunitPlumbing;
3+
using Elasticsearch.Net;
4+
using FluentAssertions;
5+
using Nest;
6+
7+
namespace Tests.CodeStandards.Serialization
8+
{
9+
public class FractionalNumbers
10+
{
11+
private readonly IElasticsearchSerializer _serializer;
12+
13+
public FractionalNumbers()
14+
{
15+
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
16+
var settings = new ConnectionSettings(pool, new InMemoryConnection());
17+
var client = new ElasticClient(settings);
18+
_serializer = client.RequestResponseSerializer;
19+
}
20+
21+
[U]
22+
public void SerializeDouble()
23+
{
24+
var poco = new
25+
{
26+
Whole = 1d,
27+
Fractional = 1.1d
28+
};
29+
30+
var serialized = _serializer.SerializeToString(poco);
31+
serialized.Should().Be("{\"whole\":1.0,\"fractional\":1.1}");
32+
}
33+
34+
[U]
35+
public void SerializeFloat()
36+
{
37+
var poco = new
38+
{
39+
Whole = 1f,
40+
Fractional = 1.1f
41+
};
42+
43+
var serialized = _serializer.SerializeToString(poco);
44+
serialized.Should().Be("{\"whole\":1.0,\"fractional\":1.1}");
45+
}
46+
47+
[U]
48+
public void SerializeDecimal()
49+
{
50+
var poco = new
51+
{
52+
Whole = 1m,
53+
Fractional = 1.1m
54+
};
55+
56+
var serialized = _serializer.SerializeToString(poco);
57+
serialized.Should().Be("{\"whole\":1.0,\"fractional\":1.1}");
58+
}
59+
}
60+
}

src/Tests/Tests/QueryDsl/Compound/Bool/BoolQueryUsageTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ public BoolQueryUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(
127127
new { match_all = new { } }
128128
},
129129
minimum_should_match = 1,
130-
boost = 2,
130+
boost = 2.0,
131131
}
132132
};
133133

0 commit comments

Comments
 (0)