You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by fl...@apache.org on 2020/04/01 09:55:35 UTC
[tinkerpop] 01/01: TINKERPOP-2349 Migrate to System.Text.Json
This is an automated email from the ASF dual-hosted git repository.
florianhockmann pushed a commit to branch TINKERPOP-2349
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 2cbcbfb17539a20250893d5346e33dd3e66e10f1
Author: Florian Hockmann <fh...@florian-hockmann.de>
AuthorDate: Mon Mar 30 16:51:45 2020 +0200
TINKERPOP-2349 Migrate to System.Text.Json
.NET Core 3.0 is added as a target framework as it already includes
support for System.Text.Json and therefore doesn't need the NuGet
package.
Results from a simple benchmark with BenchmarkDotNet showed that this
improves the performance of the deserialization roughly by a factor of
2. The deserialization now also allocates far less memory, by a factor
of ~7 which also results in less garbage collections.
The performance of the serialization however stayed basically the same.
It got even slightly slower by ~4% in this benchmark, but it also
allocates a bit less memory (-12%). This seems acceptable in my opinion,
given that it is only a very small increase, especially compared to the
differences for the deserialization and because it allocates less
memory now.
Output from BenchmarkDotNet:
Before:
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------------- |---------:|---------:|---------:|-------:|-------:|------:|----------:|
| Serialization | 22.41 us | 0.616 us | 0.659 us | 1.5564 | - | - | 9.72 KB |
| Deserialization | 40.50 us | 1.075 us | 1.150 us | 6.3477 | 0.6104 | - | 39.06 KB |
After:
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------------- |---------:|---------:|---------:|-------:|------:|------:|----------:|
| Serialization | 23.25 us | 0.103 us | 0.091 us | 1.3733 | - | - | 8.58 KB |
| Deserialization | 25.89 us | 0.583 us | 0.545 us | 0.9155 | - | - | 5.74 KB |
---
docs/src/upgrade/release-3.5.x.asciidoc | 17 +-
gremlin-dotnet/glv/Gremlin.Net.csproj.template | 13 +-
.../src/Gremlin.Net/Driver/Connection.cs | 7 +-
.../Gremlin.Net/Driver/JsonMessageSerializer.cs | 12 +-
.../Gremlin.Net/Driver/Messages/ResponseMessage.cs | 6 +-
.../Gremlin.Net/Driver/Messages/ResponseResult.cs | 9 +-
.../Gremlin.Net/Driver/Messages/ResponseStatus.cs | 8 +-
.../Driver/SingleMessageResultReceiver.cs | 6 +-
gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj | 13 +-
.../IO/GraphSON/BigIntegerDeserializer.cs | 7 +-
.../Structure/IO/GraphSON/BulkSetSerializer.cs | 14 +-
.../IO/GraphSON/ByteBufferDeserializer.cs | 6 +-
.../Structure/IO/GraphSON/ByteConverter.cs | 6 +-
.../Structure/IO/GraphSON/CharConverter.cs | 10 +-
.../Structure/IO/GraphSON/DateDeserializer.cs | 6 +-
.../Structure/IO/GraphSON/DecimalConverter.cs | 14 +-
.../Structure/IO/GraphSON/DirectionDeserializer.cs | 6 +-
.../Structure/IO/GraphSON/DoubleConverter.cs | 45 +-
.../Structure/IO/GraphSON/DurationDeserializer.cs | 6 +-
.../Structure/IO/GraphSON/EdgeDeserializer.cs | 22 +-
.../Structure/IO/GraphSON/FloatConverter.cs | 6 +-
.../Structure/IO/GraphSON/GraphSONReader.cs | 64 ++-
.../Structure/IO/GraphSON/GraphSONWriter.cs | 9 +-
.../Structure/IO/GraphSON/IGraphSONDeserializer.cs | 4 +-
.../Structure/IO/GraphSON/Int16Converter.cs | 7 +-
.../Structure/IO/GraphSON/Int32Converter.cs | 7 +-
.../Structure/IO/GraphSON/Int64Converter.cs | 7 +-
.../Structure/IO/GraphSON/ListSerializer.cs | 15 +-
.../Structure/IO/GraphSON/MapSerializer.cs | 16 +-
.../Structure/IO/GraphSON/NumberConverter.cs | 17 +-
.../Structure/IO/GraphSON/Path3Deserializer.cs | 8 +-
.../Structure/IO/GraphSON/PathDeserializer.cs | 12 +-
.../Structure/IO/GraphSON/PropertyDeserializer.cs | 12 +-
.../Structure/IO/GraphSON/SetSerializer.cs | 10 +-
.../Structure/IO/GraphSON/TDeserializer.cs | 6 +-
.../Structure/IO/GraphSON/TraverserReader.cs | 8 +-
.../Structure/IO/GraphSON/UuidDeserializer.cs | 8 +-
.../Structure/IO/GraphSON/VertexDeserializer.cs | 10 +-
.../IO/GraphSON/VertexPropertyDeserializer.cs | 14 +-
.../Docs/Dev/Provider/IndexTests.cs | 8 +-
.../Driver/GremlinClientTests.cs | 42 +-
.../Gherkin/CommonSteps.cs | 63 ++-
.../Driver/JsonMessageSerializerTests.cs | 11 +-
.../Gremlin.Net.UnitTest.csproj | 1 -
.../Structure/IO/GraphSON/GraphSONReaderTests.cs | 572 +++++++++++----------
.../Structure/IO/GraphSON/GraphSONWriterTests.cs | 2 +
46 files changed, 652 insertions(+), 520 deletions(-)
diff --git a/docs/src/upgrade/release-3.5.x.asciidoc b/docs/src/upgrade/release-3.5.x.asciidoc
index 12765e7..b8516c6 100644
--- a/docs/src/upgrade/release-3.5.x.asciidoc
+++ b/docs/src/upgrade/release-3.5.x.asciidoc
@@ -213,11 +213,24 @@ See: link:https://issues.apache.org/jira/browse/TINKERPOP-2317[TINKERPOP-2317]
==== .NET Standard 2.0 Only
-Gremlin.NET no longer targets .NET Standard 1.3, but only .NET Standard 2.0. Since .NET Core 2.0 and .NET Framework
-4.6.1 already support this .NET Standard version, most users should not be impacted by this.
+Gremlin.NET no longer targets .NET Standard 1.3, but only .NET Standard 2.0 (and .NET Core 3.0). Since .NET Core 2.0
+and .NET Framework 4.6.1 already support this .NET Standard version, most users should not be impacted by this.
See: link:https://issues.apache.org/jira/browse/TINKERPOP-2335[TINKERPOP-2335]
+=== Gremlin.NET: New JSON Library
+
+Gremlin.NET now uses `System.Text.Json` instead of Newtonsoft.Json as `System.Text.Json` is already included in .NET
+Core 3.0 and higher which means that we have one dependency less on this platform and because it offers an increased
+performance.
+Most users should not notice this change. But users who have implemented their own GraphSON serializers or
+deserializers probably have to change them accordingly. The same applies to users that let Gremlin.NET return data
+without deserializing it first as the returned data types will change in this case, for example from Newtonsoft.Json's
+`JObject` or `JToken` to `JsonElement` with `System.Text.Json`.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-2349[TINKERPOP-2349],
+link:http://tinkerpop.apache.org/docs/3.5.0/dev/provider/#_supporting_gremlin_net_io[Documentation for custom JSON serialization with Gremlin.NET]
+
==== Neo4j Changes
There were two key changes to the neo4j-gremlin module:
diff --git a/gremlin-dotnet/glv/Gremlin.Net.csproj.template b/gremlin-dotnet/glv/Gremlin.Net.csproj.template
index a6a57a3..41255da 100644
--- a/gremlin-dotnet/glv/Gremlin.Net.csproj.template
+++ b/gremlin-dotnet/glv/Gremlin.Net.csproj.template
@@ -19,7 +19,7 @@ limitations under the License.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Build">
- <TargetFramework>netstandard2.0</TargetFramework>
+ <TargetFrameworks>netstandard2.0;netcoreapp3.0</TargetFrameworks>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
@@ -60,14 +60,17 @@ NOTE that versions suffixed with "-rc" are considered release candidates (i.e. p
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
- <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
+ <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.CSharp" Version="4.3.0" />
</ItemGroup>
+ <ItemGroup Condition="'\$(TargetFramework)' == 'netstandard2.0'">
+ <PackageReference Include="System.Text.Json" Version="4.7.1" />
+ </ItemGroup>
+
<ItemGroup>
- <None Include="../../LICENSE" Pack="true" PackagePath=""/>
- <None Include="../../NOTICE" Pack="true" PackagePath=""/>
+ <None Include="../../LICENSE" Pack="true" PackagePath="" />
+ <None Include="../../NOTICE" Pack="true" PackagePath="" />
</ItemGroup>
</Project>
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs
index bfb467d..6cd603c 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Connection.cs
@@ -31,13 +31,12 @@ using System.Threading.Tasks;
using Gremlin.Net.Driver.Messages;
using Gremlin.Net.Process;
using Gremlin.Net.Structure.IO.GraphSON;
-using Newtonsoft.Json.Linq;
namespace Gremlin.Net.Driver
{
internal interface IResponseHandlerForSingleRequestMessage
{
- void HandleReceived(ResponseMessage<JToken> received);
+ void HandleReceived(ResponseMessage received);
void Finalize(Dictionary<string, object> statusAttributes);
void HandleFailure(Exception objException);
}
@@ -116,7 +115,7 @@ namespace Gremlin.Net.Driver
private void Parse(byte[] received)
{
- var receivedMsg = _messageSerializer.DeserializeMessage<ResponseMessage<JToken>>(received);
+ var receivedMsg = _messageSerializer.DeserializeMessage<ResponseMessage>(received);
if (receivedMsg == null)
{
ThrowMessageDeserializedNull();
@@ -138,7 +137,7 @@ namespace Gremlin.Net.Driver
private static void ThrowMessageDeserializedNull() =>
throw new InvalidOperationException("Received data deserialized into null object message. Cannot operate on it.");
- private void TryParseResponseMessage(ResponseMessage<JToken> receivedMsg)
+ private void TryParseResponseMessage(ResponseMessage receivedMsg)
{
var status = receivedMsg.Status;
status.ThrowIfStatusIndicatesError();
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs
index 53a546c..de4c610 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/JsonMessageSerializer.cs
@@ -21,14 +21,17 @@
#endregion
+using System;
using System.Text;
-using Newtonsoft.Json;
+using System.Text.Json;
namespace Gremlin.Net.Driver
{
internal class JsonMessageSerializer
{
private readonly string _mimeType;
+ private static readonly JsonSerializerOptions JsonDeserializingOptions = new JsonSerializerOptions
+ {PropertyNamingPolicy = JsonNamingPolicy.CamelCase};
public JsonMessageSerializer(string mimeType)
{
@@ -47,8 +50,11 @@ namespace Gremlin.Net.Driver
public TMessage DeserializeMessage<TMessage>(byte[] message)
{
- var responseStr = Encoding.UTF8.GetString(message);
- return JsonConvert.DeserializeObject<TMessage>(responseStr);
+ if (message == null) throw new ArgumentNullException(nameof(message));
+ if (message.Length == 0) return default;
+ var reader = new Utf8JsonReader(message);
+ var deserialized = JsonSerializer.Deserialize<TMessage>(ref reader, JsonDeserializingOptions);
+ return deserialized;
}
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs
index f1cb3ad..791433f 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseMessage.cs
@@ -22,19 +22,15 @@
#endregion
using System;
-using Newtonsoft.Json;
namespace Gremlin.Net.Driver.Messages
{
- internal class ResponseMessage<T>
+ internal class ResponseMessage
{
- [JsonProperty(PropertyName = "requestId")]
public Guid RequestId { get; set; }
- [JsonProperty(PropertyName = "status")]
public ResponseStatus Status { get; set; }
- [JsonProperty(PropertyName = "result")]
public ResponseResult Result { get; set; }
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs
index 848473b..b26f415 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseResult.cs
@@ -22,17 +22,14 @@
#endregion
using System.Collections.Generic;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Driver.Messages
{
internal class ResponseResult
{
- [JsonProperty(PropertyName = "data")]
- public JToken Data { get; set; }
-
- [JsonProperty(PropertyName = "meta")]
+ public JsonElement Data { get; set; }
+
public Dictionary<string, object> Meta { get; set; }
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs
index aa0b1b7..32d8b43 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/ResponseStatus.cs
@@ -23,19 +23,15 @@
using System.Collections.Generic;
using Gremlin.Net.Driver.Exceptions;
-using Newtonsoft.Json;
namespace Gremlin.Net.Driver.Messages
{
internal class ResponseStatus
{
- [JsonProperty(PropertyName = "code")]
public ResponseStatusCode Code { get; set; }
-
- [JsonProperty(PropertyName = "attributes")]
+
public Dictionary<string, object> Attributes { get; set; }
-
- [JsonProperty(PropertyName = "message")]
+
public string Message { get; set; }
}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/SingleMessageResultReceiver.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/SingleMessageResultReceiver.cs
index a78241c..13fbaf4 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Driver/SingleMessageResultReceiver.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Driver/SingleMessageResultReceiver.cs
@@ -23,10 +23,10 @@
using System;
using System.Collections.Generic;
+using System.Text.Json;
using System.Threading.Tasks;
using Gremlin.Net.Driver.Messages;
using Gremlin.Net.Structure.IO.GraphSON;
-using Newtonsoft.Json.Linq;
namespace Gremlin.Net.Driver
{
@@ -45,9 +45,9 @@ namespace Gremlin.Net.Driver
_graphSONReader = graphSonReader;
}
- public void HandleReceived(ResponseMessage<JToken> received)
+ public void HandleReceived(ResponseMessage received)
{
- var receivedData = typeof(T) == typeof(JToken)
+ var receivedData = typeof(T) == typeof(JsonElement)
? new[] {received.Result.Data}
: _graphSONReader.ToObject(received.Result.Data);
foreach (var d in receivedData)
diff --git a/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj b/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj
index 4a43c81..f385165 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj
+++ b/gremlin-dotnet/src/Gremlin.Net/Gremlin.Net.csproj
@@ -19,7 +19,7 @@ limitations under the License.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Build">
- <TargetFramework>netstandard2.0</TargetFramework>
+ <TargetFrameworks>netstandard2.0;netcoreapp3.0</TargetFrameworks>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
@@ -60,14 +60,17 @@ NOTE that versions suffixed with "-rc" are considered release candidates (i.e. p
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
- <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
+ <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.CSharp" Version="4.3.0" />
</ItemGroup>
+ <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+ <PackageReference Include="System.Text.Json" Version="4.7.1" />
+ </ItemGroup>
+
<ItemGroup>
- <None Include="../../LICENSE" Pack="true" PackagePath=""/>
- <None Include="../../NOTICE" Pack="true" PackagePath=""/>
+ <None Include="../../LICENSE" Pack="true" PackagePath="" />
+ <None Include="../../NOTICE" Pack="true" PackagePath="" />
</ItemGroup>
</Project>
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BigIntegerDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BigIntegerDeserializer.cs
index 755dbcc..a3f1ff6 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BigIntegerDeserializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BigIntegerDeserializer.cs
@@ -22,16 +22,15 @@
#endregion
using System.Numerics;
-using System.Xml;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class BigIntegerDeserializer : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphson, GraphSONReader reader)
{
- var bigInteger = graphsonObject.ToObject<string>();
+ var bigInteger = graphson.ValueKind == JsonValueKind.String ? graphson.GetString() : graphson.GetRawText();
return BigInteger.Parse(bigInteger);
}
}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BulkSetSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BulkSetSerializer.cs
index 58d4c9b..539224a 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BulkSetSerializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/BulkSetSerializer.cs
@@ -23,17 +23,15 @@
using System.Collections.Generic;
using System.Linq;
-using System.Runtime.CompilerServices;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class BulkSetSerializer : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- var jArray = graphsonObject as JArray;
- if (jArray == null)
+ if (graphsonObject.ValueKind != JsonValueKind.Array)
{
return new List<object>(0);
}
@@ -42,9 +40,9 @@ namespace Gremlin.Net.Structure.IO.GraphSON
// so this query will be trouble. we'd need a legit BulkSet implementation here in C#. this current
// implementation is here to replicate the previous functionality that existed on the server side in
// previous versions.
- return Enumerable.Range(0, jArray.Count / 2).SelectMany<int,object>(i =>
- Enumerable.Repeat<object>(reader.ToObject(jArray[i * 2]), (int) reader.ToObject(jArray[i * 2 + 1]))).
- ToList();
+ return Enumerable.Range(0, graphsonObject.GetArrayLength() / 2).SelectMany<int, object>(i =>
+ Enumerable.Repeat<object>(reader.ToObject(graphsonObject[i * 2]),
+ (int) reader.ToObject(graphsonObject[i * 2 + 1]))).ToList();
}
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ByteBufferDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ByteBufferDeserializer.cs
index f77abb0..0feb3a2 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ByteBufferDeserializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ByteBufferDeserializer.cs
@@ -21,15 +21,15 @@
#endregion
using System;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class ByteBufferDeserializer : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- var base64String = graphsonObject.ToObject<string>();
+ var base64String = graphsonObject.GetString();
return Convert.FromBase64String(base64String);
}
}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ByteConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ByteConverter.cs
index 6525d52..c9fc8a5 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ByteConverter.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ByteConverter.cs
@@ -20,14 +20,14 @@
*/
#endregion
-using System;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
- internal class ByteConverter : NumberConverter
+ internal class ByteConverter : NumberConverter<byte>
{
protected override string GraphSONTypeName => "Byte";
- protected override Type HandledType => typeof(byte);
protected override string Prefix => "gx";
+ protected override dynamic FromJsonElement(JsonElement graphson) => graphson.GetByte();
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/CharConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/CharConverter.cs
index b7023be..0c3e539 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/CharConverter.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/CharConverter.cs
@@ -20,15 +20,19 @@
*/
#endregion
-using System;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
- internal class CharConverter : NumberConverter
+ internal class CharConverter : NumberConverter<char>
{
protected override string GraphSONTypeName => "Char";
- protected override Type HandledType => typeof(char);
protected override string Prefix => "gx";
protected override bool StringifyValue => true;
+ protected override dynamic FromJsonElement(JsonElement graphson)
+ {
+ var deserializedByte = graphson.GetString();
+ return deserializedByte[0];
+ }
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs
index 98ca25e..bc5bf61 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DateDeserializer.cs
@@ -21,7 +21,7 @@
#endregion
using System;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
@@ -29,9 +29,9 @@ namespace Gremlin.Net.Structure.IO.GraphSON
{
private static readonly DateTimeOffset UnixStart = new DateTimeOffset(1970, 1, 1, 0, 0, 0, 0, TimeSpan.Zero);
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- var milliseconds = graphsonObject.ToObject<long>();
+ var milliseconds = graphsonObject.GetInt64();
return UnixStart.AddTicks(TimeSpan.TicksPerMillisecond * milliseconds);
}
}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DecimalConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DecimalConverter.cs
index 6860137..f195522 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DecimalConverter.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DecimalConverter.cs
@@ -21,15 +21,23 @@
#endregion
-using System;
+using System.Globalization;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
- internal class DecimalConverter : NumberConverter
+ internal class DecimalConverter : NumberConverter<decimal>
{
protected override string GraphSONTypeName => "BigDecimal";
- protected override Type HandledType => typeof(decimal);
protected override string Prefix => "gx";
protected override bool StringifyValue => true;
+ protected override dynamic FromJsonElement(JsonElement graphson)
+ {
+ if (graphson.ValueKind == JsonValueKind.String)
+ {
+ return decimal.Parse(graphson.GetString(), CultureInfo.InvariantCulture);
+ }
+ return graphson.GetDecimal();
+ }
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DirectionDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DirectionDeserializer.cs
index 4027171..34d4f61 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DirectionDeserializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DirectionDeserializer.cs
@@ -21,16 +21,16 @@
#endregion
+using System.Text.Json;
using Gremlin.Net.Process.Traversal;
-using Newtonsoft.Json.Linq;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class DirectionDeserializer : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- return Direction.GetByValue(graphsonObject.ToString());
+ return Direction.GetByValue(graphsonObject.GetString());
}
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs
index 416423b..ba5a2f7 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DoubleConverter.cs
@@ -21,13 +21,52 @@
#endregion
-using System;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
- internal class DoubleConverter : NumberConverter
+ internal class DoubleConverter : NumberConverter<double>
{
protected override string GraphSONTypeName => "Double";
- protected override Type HandledType => typeof(double);
+ private const string NaN = "NaN";
+ private const string PositiveInfinity = "Infinity";
+ private const string NegativeInfinity = "-Infinity";
+
+ protected override dynamic FromJsonElement(JsonElement graphson)
+ {
+ if (graphson.ValueKind == JsonValueKind.String)
+ {
+ switch (graphson.GetString())
+ {
+ case NaN:
+ return double.NaN;
+ case PositiveInfinity:
+ return double.PositiveInfinity;
+ case NegativeInfinity:
+ return double.NegativeInfinity;
+ }
+ }
+ return graphson.GetDouble();
+ }
+
+ protected override object ConvertInvalidNumber(double number)
+ {
+ if (double.IsNaN(number))
+ {
+ return NaN;
+ }
+
+ if (double.IsPositiveInfinity(number))
+ {
+ return PositiveInfinity;
+ }
+
+ if (double.IsNegativeInfinity(number))
+ {
+ return NegativeInfinity;
+ }
+
+ return number;
+ }
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DurationDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DurationDeserializer.cs
index 00a9a70..2c1d17f 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DurationDeserializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/DurationDeserializer.cs
@@ -21,16 +21,16 @@
#endregion
+using System.Text.Json;
using System.Xml;
-using Newtonsoft.Json.Linq;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class DurationDeserializer : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- var duration = graphsonObject.ToObject<string>();
+ var duration = graphsonObject.GetString();
return XmlConvert.ToTimeSpan(duration);
}
}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs
index 6ec8694..13f4ce0 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/EdgeDeserializer.cs
@@ -21,22 +21,28 @@
#endregion
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class EdgeDeserializer : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- var outVId = reader.ToObject(graphsonObject["outV"]);
- var outVLabel = (string) (graphsonObject["outVLabel"] ?? Vertex.DefaultLabel);
+ var outVId = reader.ToObject(graphsonObject.GetProperty("outV"));
+ var outVLabel = graphsonObject.TryGetProperty("outVLabel", out var outVLabelProperty)
+ ? outVLabelProperty.GetString()
+ : Vertex.DefaultLabel;
var outV = new Vertex(outVId, outVLabel);
- var inVId = reader.ToObject(graphsonObject["inV"]);
- var inVLabel = (string) (graphsonObject["inVLabel"] ?? Vertex.DefaultLabel);
+ var inVId = reader.ToObject(graphsonObject.GetProperty("inV"));
+ var inVLabel = graphsonObject.TryGetProperty("inVLabel", out var inVLabelProperty)
+ ? inVLabelProperty.GetString()
+ : Vertex.DefaultLabel;
var inV = new Vertex(inVId, inVLabel);
- var edgeId = reader.ToObject(graphsonObject["id"]);
- var edgeLabel = (string) graphsonObject["label"] ?? "edge";
+ var edgeId = reader.ToObject(graphsonObject.GetProperty("id"));
+ var edgeLabel = graphsonObject.TryGetProperty("label", out var labelProperty)
+ ? labelProperty.GetString()
+ : "edge";
return new Edge(edgeId, outV, edgeLabel, inV);
}
}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs
index 432aeab..5bbd9b2 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/FloatConverter.cs
@@ -21,13 +21,13 @@
#endregion
-using System;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
- internal class FloatConverter : NumberConverter
+ internal class FloatConverter : NumberConverter<float>
{
protected override string GraphSONTypeName => "Float";
- protected override Type HandledType => typeof(float);
+ protected override dynamic FromJsonElement(JsonElement graphson) => graphson.GetSingle();
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs
index 63641f0..16901bd 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONReader.cs
@@ -24,7 +24,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
@@ -90,7 +90,7 @@ namespace Gremlin.Net.Structure.IO.GraphSON
/// </summary>
/// <param name="graphSonData">The GraphSON collection to deserialize.</param>
/// <returns>The deserialized object.</returns>
- public virtual dynamic ToObject(IEnumerable<JToken> graphSonData)
+ public virtual dynamic ToObject(IEnumerable<JsonElement> graphSonData)
{
return graphSonData.Select(graphson => ToObject(graphson));
}
@@ -98,52 +98,50 @@ namespace Gremlin.Net.Structure.IO.GraphSON
/// <summary>
/// Deserializes GraphSON to an object.
/// </summary>
- /// <param name="jToken">The GraphSON to deserialize.</param>
+ /// <param name="graphSon">The GraphSON to deserialize.</param>
/// <returns>The deserialized object.</returns>
- public virtual dynamic ToObject(JToken jToken)
+ public virtual dynamic ToObject(JsonElement graphSon)
{
- if (jToken is JArray)
+ switch (graphSon.ValueKind)
{
- return jToken.Select(t => ToObject(t));
+ case JsonValueKind.Array:
+ return graphSon.EnumerateArray().Select(t => ToObject(t));
+ case JsonValueKind.String:
+ return graphSon.GetString();
+ case JsonValueKind.Null:
+ return null;
+ case JsonValueKind.True:
+ return true;
+ case JsonValueKind.False:
+ return false;
+ case JsonValueKind.Object:
+ break;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(graphSon.ValueKind), graphSon.ValueKind,
+ $"JSON type not supported.");
}
- if (jToken is JValue jValue)
- {
- return jValue.Value;
- }
- if (!HasTypeKey(jToken))
+
+ if (graphSon.TryGetProperty(GraphSONTokens.TypeKey, out var graphSonTypeProperty))
{
- return ReadDictionary(jToken);
+ return ReadValueOfType(graphSon, graphSonTypeProperty.GetString());
}
- return ReadTypedValue(jToken);
+ return ReadDictionary(graphSon);
+
}
- private bool HasTypeKey(JToken jToken)
+ private dynamic ReadValueOfType(JsonElement typedValue, string graphSONType)
{
- var graphSONType = (string) jToken[GraphSONTokens.TypeKey];
- return graphSONType != null;
- }
-
- private dynamic ReadTypedValue(JToken typedValue)
- {
- var graphSONType = (string) typedValue[GraphSONTokens.TypeKey];
if (!Deserializers.TryGetValue(graphSONType, out var deserializer))
{
throw new InvalidOperationException($"Deserializer for \"{graphSONType}\" not found");
}
- return deserializer.Objectify(typedValue[GraphSONTokens.ValueKey], this);
+ return deserializer.Objectify(typedValue.GetProperty(GraphSONTokens.ValueKey), this);
}
-
- private dynamic ReadDictionary(JToken jtokenDict)
+
+ private dynamic ReadDictionary(JsonElement jsonDict)
{
- var dict = new Dictionary<string, dynamic>();
- foreach (var e in jtokenDict)
- {
- var property = e as JProperty;
- if (property == null)
- throw new InvalidOperationException($"Cannot read graphson: {jtokenDict}");
- dict.Add(property.Name, ToObject(property.Value));
- }
- return dict;
+ return jsonDict.EnumerateObject()
+ .ToDictionary(property => property.Name, property => ToObject(property.Value));
}
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
index f119c01..dd4fa27 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/GraphSONWriter.cs
@@ -26,11 +26,11 @@ using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
-using System.Reflection;
+using System.Text.Encodings.Web;
+using System.Text.Json;
using Gremlin.Net.Driver.Messages;
using Gremlin.Net.Process.Traversal;
using Gremlin.Net.Process.Traversal.Strategy;
-using Newtonsoft.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
@@ -39,6 +39,9 @@ namespace Gremlin.Net.Structure.IO.GraphSON
/// </summary>
public abstract class GraphSONWriter
{
+ private static readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions
+ {Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping};
+
/// <summary>
/// Contains the information of serializers by type.
/// </summary>
@@ -103,7 +106,7 @@ namespace Gremlin.Net.Structure.IO.GraphSON
/// <returns>The serialized GraphSON.</returns>
public virtual string WriteObject(dynamic objectData)
{
- return JsonConvert.SerializeObject(ToDict(objectData));
+ return JsonSerializer.Serialize(ToDict(objectData), _jsonOptions);
}
/// <summary>
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs
index b15b169..e0c4993 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/IGraphSONDeserializer.cs
@@ -21,7 +21,7 @@
#endregion
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
@@ -36,6 +36,6 @@ namespace Gremlin.Net.Structure.IO.GraphSON
/// <param name="graphsonObject">The GraphSON object to objectify.</param>
/// <param name="reader">A <see cref="GraphSONReader" /> that can be used to objectify properties of the GraphSON object.</param>
/// <returns>The deserialized object.</returns>
- dynamic Objectify(JToken graphsonObject, GraphSONReader reader);
+ dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader);
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int16Converter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int16Converter.cs
index abe5a77..6182de9 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int16Converter.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int16Converter.cs
@@ -21,14 +21,15 @@
#endregion
-using System;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
- internal class Int16Converter : NumberConverter
+ internal class Int16Converter : NumberConverter<short>
{
protected override string GraphSONTypeName => "Int16";
- protected override Type HandledType => typeof(short);
protected override string Prefix => "gx";
+
+ protected override dynamic FromJsonElement(JsonElement graphson) => graphson.GetInt16();
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs
index 052f938..6cdcdfd 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int32Converter.cs
@@ -21,13 +21,14 @@
#endregion
-using System;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
- internal class Int32Converter : NumberConverter
+ internal class Int32Converter : NumberConverter<int>
{
protected override string GraphSONTypeName => "Int32";
- protected override Type HandledType => typeof(int);
+
+ protected override dynamic FromJsonElement(JsonElement graphson) => graphson.GetInt32();
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs
index dd0160f..c0192a8 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Int64Converter.cs
@@ -21,13 +21,14 @@
#endregion
-using System;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
- internal class Int64Converter : NumberConverter
+ internal class Int64Converter : NumberConverter<long>
{
protected override string GraphSONTypeName => "Int64";
- protected override Type HandledType => typeof(long);
+
+ protected override dynamic FromJsonElement(JsonElement graphson) => graphson.GetInt64();
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ListSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ListSerializer.cs
index f432c7e..add8eb5 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ListSerializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/ListSerializer.cs
@@ -21,12 +21,8 @@
#endregion
-using System;
-using System.Collections;
using System.Collections.Generic;
-using System.Linq;
-using Microsoft.Win32.SafeHandles;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
@@ -34,17 +30,16 @@ namespace Gremlin.Net.Structure.IO.GraphSON
{
private static readonly IReadOnlyList<object> EmptyList = new object[0];
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- var jArray = graphsonObject as JArray;
- if (jArray == null)
+ if (graphsonObject.ValueKind != JsonValueKind.Array)
{
return EmptyList;
}
- var result = new object[jArray.Count];
+ var result = new object[graphsonObject.GetArrayLength()];
for (var i = 0; i < result.Length; i++)
{
- result[i] = reader.ToObject(jArray[i]);
+ result[i] = reader.ToObject(graphsonObject[i]);
}
// object[] implements IList<object>
return result;
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/MapSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/MapSerializer.cs
index a096e3e..99165a7 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/MapSerializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/MapSerializer.cs
@@ -24,23 +24,22 @@
using System;
using System.Collections;
using System.Collections.Generic;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class MapSerializer : IGraphSONDeserializer, IGraphSONSerializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- var jArray = graphsonObject as JArray;
- if (jArray == null)
+ if (graphsonObject.ValueKind != JsonValueKind.Array)
{
return new Dictionary<object, object>(0);
}
- var result = new Dictionary<object, object>(jArray.Count / 2);
- for (var i = 0; i < jArray.Count; i += 2)
+ var result = new Dictionary<object, object>(graphsonObject.GetArrayLength() / 2);
+ for (var i = 0; i < graphsonObject.GetArrayLength(); i += 2)
{
- result[reader.ToObject(jArray[i])] = reader.ToObject(jArray[i + 1]);
+ result[reader.ToObject(graphsonObject[i])] = reader.ToObject(graphsonObject[i + 1]);
}
// IDictionary<object, object>
return result;
@@ -48,8 +47,7 @@ namespace Gremlin.Net.Structure.IO.GraphSON
public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
{
- var map = objectData as IDictionary;
- if (map == null)
+ if (!(objectData is IDictionary map))
{
throw new InvalidOperationException("Object must implement IDictionary");
}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs
index 8127415..4492685 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/NumberConverter.cs
@@ -21,33 +21,36 @@
#endregion
-using System;
using System.Collections.Generic;
using System.Globalization;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
- internal abstract class NumberConverter : IGraphSONDeserializer, IGraphSONSerializer
+ internal abstract class NumberConverter<T> : IGraphSONDeserializer, IGraphSONSerializer
{
protected abstract string GraphSONTypeName { get; }
- protected abstract Type HandledType { get; }
protected virtual string Prefix => "g";
protected virtual bool StringifyValue => false;
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- return graphsonObject.ToObject(HandledType);
+ return FromJsonElement(graphsonObject);
}
+ protected abstract dynamic FromJsonElement(JsonElement graphson);
+
public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
{
- object value = objectData;
+ T number = objectData;
+ var value = ConvertInvalidNumber(number);
if (StringifyValue)
{
value = string.Format(CultureInfo.InvariantCulture, "{0}", value);
}
return GraphSONUtil.ToTypedValue(GraphSONTypeName, value, Prefix);
}
+
+ protected virtual object ConvertInvalidNumber(T number) => number;
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Path3Deserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Path3Deserializer.cs
index 4754135..d05663b 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Path3Deserializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/Path3Deserializer.cs
@@ -23,21 +23,21 @@
using System.Collections.Generic;
using System.Linq;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class Path3Deserializer : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
// "labels" is a object[] where each item is ISet<object>
- var labelProperty = (object[])reader.ToObject(graphsonObject["labels"]);
+ var labelProperty = (object[])reader.ToObject(graphsonObject.GetProperty("labels"));
var labels = labelProperty
.Select(x => new HashSet<string>(((ISet<object>)x).Cast<string>()))
.ToList<ISet<string>>();
// "objects" is an object[]
- object[] objects = reader.ToObject(graphsonObject["objects"]);
+ object[] objects = reader.ToObject(graphsonObject.GetProperty("objects"));
return new Path(labels, objects);
}
}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs
index b322df8..3a37f66 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PathDeserializer.cs
@@ -23,19 +23,21 @@
using System.Collections.Generic;
using System.Linq;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class PathDeserializer : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
var labels =
- graphsonObject["labels"]
- .Select(readObjLabels => new HashSet<string>(readObjLabels.Select(l => (string) l)))
+ graphsonObject.GetProperty("labels").EnumerateArray()
+ .Select(readObjLabels =>
+ new HashSet<string>(readObjLabels.EnumerateArray().Select(l => l.GetString())))
.ToList<ISet<string>>();
- var objects = graphsonObject["objects"].Select(o => reader.ToObject(o)).ToList();
+ var objects = graphsonObject.GetProperty("objects").EnumerateArray().Select(o => reader.ToObject(o))
+ .ToList();
return new Path(labels, objects);
}
}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs
index 11f160e..7c9ea0c 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/PropertyDeserializer.cs
@@ -21,17 +21,19 @@
#endregion
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class PropertyDeserializer : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- var key = (string) graphsonObject["key"];
- var value = reader.ToObject(graphsonObject["value"]);
- var element = graphsonObject["element"] != null ? reader.ToObject(graphsonObject["element"]) : null;
+ var key = graphsonObject.GetProperty("key").GetString();
+ var value = reader.ToObject(graphsonObject.GetProperty("value"));
+ var element = graphsonObject.TryGetProperty("element", out var elementProperty)
+ ? reader.ToObject(elementProperty)
+ : null;
return new Property(key, value, element);
}
}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/SetSerializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/SetSerializer.cs
index e657bd8..590392e 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/SetSerializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/SetSerializer.cs
@@ -21,24 +21,22 @@
#endregion
-using System;
using System.Collections.Generic;
using System.Linq;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class SetSerializer : IGraphSONDeserializer, IGraphSONSerializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- var jArray = graphsonObject as JArray;
- if (jArray == null)
+ if (graphsonObject.ValueKind != JsonValueKind.Array)
{
return new HashSet<object>();
}
// ISet<object>
- return new HashSet<object>(jArray.Select(reader.ToObject));
+ return new HashSet<object>(graphsonObject.EnumerateArray().Select(reader.ToObject));
}
public Dictionary<string, dynamic> Dictify(dynamic objectData, GraphSONWriter writer)
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TDeserializer.cs
index a3d972f..efbc542 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TDeserializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TDeserializer.cs
@@ -21,16 +21,16 @@
#endregion
+using System.Text.Json;
using Gremlin.Net.Process.Traversal;
-using Newtonsoft.Json.Linq;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class TDeserializer : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- return T.GetByValue(graphsonObject.ToString());
+ return T.GetByValue(graphsonObject.GetString());
}
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraverserReader.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraverserReader.cs
index abbb45f..1997325 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraverserReader.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/TraverserReader.cs
@@ -21,17 +21,17 @@
#endregion
+using System.Text.Json;
using Gremlin.Net.Process.Traversal;
-using Newtonsoft.Json.Linq;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class TraverserReader : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- var bulkObj = reader.ToObject(graphsonObject["bulk"]);
- var valueObj = reader.ToObject(graphsonObject["value"]);
+ var bulkObj = reader.ToObject(graphsonObject.GetProperty("bulk"));
+ var valueObj = reader.ToObject(graphsonObject.GetProperty("value"));
return new Traverser(valueObj, bulkObj);
}
}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidDeserializer.cs
index 82ca43d..58caac7 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidDeserializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/UuidDeserializer.cs
@@ -22,15 +22,17 @@
#endregion
using System;
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class UuidDeserializer : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- return graphsonObject.ToObject<Guid>();
+ var uuidString = graphsonObject.GetString();
+
+ return Guid.Parse(uuidString);
}
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexDeserializer.cs
index f1d64ed..72615ef 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexDeserializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexDeserializer.cs
@@ -21,16 +21,18 @@
#endregion
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class VertexDeserializer : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- var id = reader.ToObject(graphsonObject["id"]);
- var label = (string) graphsonObject["label"] ?? Vertex.DefaultLabel;
+ var id = reader.ToObject(graphsonObject.GetProperty("id"));
+ var label = graphsonObject.TryGetProperty("label", out var labelProperty)
+ ? labelProperty.GetString()
+ : Vertex.DefaultLabel;
return new Vertex(id, label);
}
}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertyDeserializer.cs b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertyDeserializer.cs
index 7c2505f..15a99dc 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertyDeserializer.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Structure/IO/GraphSON/VertexPropertyDeserializer.cs
@@ -21,19 +21,19 @@
#endregion
-using Newtonsoft.Json.Linq;
+using System.Text.Json;
namespace Gremlin.Net.Structure.IO.GraphSON
{
internal class VertexPropertyDeserializer : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- var id = reader.ToObject(graphsonObject["id"]);
- var label = (string) graphsonObject["label"];
- var value = reader.ToObject(graphsonObject["value"]);
- var vertex = graphsonObject["vertex"] != null
- ? new Vertex(reader.ToObject(graphsonObject["vertex"]))
+ var id = reader.ToObject(graphsonObject.GetProperty("id"));
+ var label = graphsonObject.GetProperty("label").GetString();
+ var value = reader.ToObject(graphsonObject.GetProperty("value"));
+ var vertex = graphsonObject.TryGetProperty("vertex", out var vertexProperty)
+ ? new Vertex(reader.ToObject(vertexProperty))
: null;
return new VertexProperty(id, label, value, vertex);
}
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Dev/Provider/IndexTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Dev/Provider/IndexTests.cs
index 6d8cda2..906a117 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Dev/Provider/IndexTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Dev/Provider/IndexTests.cs
@@ -23,9 +23,9 @@
using System;
using System.Collections.Generic;
+using System.Text.Json;
using Gremlin.Net.Driver;
using Gremlin.Net.Structure.IO.GraphSON;
-using Newtonsoft.Json.Linq;
using Xunit;
using Xunit.Sdk;
@@ -64,10 +64,10 @@ internal class MyClassWriter : IGraphSONSerializer
internal class MyTypeReader : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- var x = reader.ToObject(graphsonObject["x"]);
- var y = reader.ToObject(graphsonObject["y"]);
+ var x = reader.ToObject(graphsonObject.GetProperty("x"));
+ var y = reader.ToObject(graphsonObject.GetProperty("y"));
return new MyType(x, y);
}
}
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs
index 6cf249c..c50f69d 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientTests.cs
@@ -24,12 +24,12 @@
using System;
using System.Collections.Generic;
using System.Net.WebSockets;
+using System.Text.Json;
using System.Threading.Tasks;
using Gremlin.Net.Driver;
using Gremlin.Net.Driver.Exceptions;
using Gremlin.Net.Driver.Messages;
using Gremlin.Net.IntegrationTest.Util;
-using Newtonsoft.Json.Linq;
using Xunit;
namespace Gremlin.Net.IntegrationTest.Driver
@@ -70,31 +70,29 @@ namespace Gremlin.Net.IntegrationTest.Driver
}
[Fact]
- public async Task ShouldReturnResultWithoutDeserializingItForJTokenType()
+ public async Task ShouldReturnResultWithoutDeserializingItForJsonElementType()
{
var gremlinServer = new GremlinServer(TestHost, TestPort);
- using (var gremlinClient = new GremlinClient(gremlinServer))
- {
- var gremlinScript = "'someString'";
+ using var gremlinClient = new GremlinClient(gremlinServer);
+ const string gremlinScript = "'someString'";
- var response = await gremlinClient.SubmitWithSingleResultAsync<JToken>(gremlinScript);
+ var response = await gremlinClient.SubmitWithSingleResultAsync<JsonElement>(gremlinScript);
- //Expected:
- /* {
+ //Expected:
+ /* {
"@type": "g:List",
"@value": [
"someString"
]
}*/
- Assert.IsType<JObject>(response);
- Assert.Equal("g:List", response["@type"]);
+ Assert.IsType<JsonElement>(response);
+ Assert.Equal("g:List", response.GetProperty("@type").GetString());
- var jArray = response["@value"] as JArray;
- Assert.NotNull(jArray);
- Assert.Equal(1, jArray.Count);
- Assert.Equal("someString", (jArray[0] as JValue)?.Value);
- }
+ var valueProperty = response.GetProperty("@value");
+ Assert.NotNull(valueProperty);
+ Assert.Equal(1, valueProperty.GetArrayLength());
+ Assert.Equal("someString", (valueProperty[0].GetString()));
}
[Fact]
@@ -201,16 +199,14 @@ namespace Gremlin.Net.IntegrationTest.Driver
public async Task ShouldReturnResponseAttributes()
{
var gremlinServer = new GremlinServer(TestHost, TestPort);
- using (var gremlinClient = new GremlinClient(gremlinServer))
- {
- var requestMsg = _requestMessageProvider.GetDummyMessage();
- var resultSet = await gremlinClient.SubmitAsync<int>(requestMsg);
+ using var gremlinClient = new GremlinClient(gremlinServer);
+ var requestMsg = _requestMessageProvider.GetDummyMessage();
+ var resultSet = await gremlinClient.SubmitAsync<int>(requestMsg);
- Assert.NotNull(resultSet.StatusAttributes);
+ Assert.NotNull(resultSet.StatusAttributes);
- var values= resultSet.StatusAttributes["@value"] as JArray;
- Assert.True(values.First.ToString().Equals("host"));
- }
+ var values = (JsonElement) resultSet.StatusAttributes["@value"];
+ Assert.True(values[0].ToString().Equals("host"));
}
[Fact]
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
index b9135ed..e4224e8 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/CommonSteps.cs
@@ -26,13 +26,13 @@ using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
+using System.Text.Json;
using System.Text.RegularExpressions;
using Gherkin.Ast;
using Gremlin.Net.IntegrationTest.Gherkin.Attributes;
using Gremlin.Net.IntegrationTest.Gherkin.TraversalEvaluation;
using Gremlin.Net.Process.Traversal;
using Gremlin.Net.Structure;
-using Newtonsoft.Json.Linq;
using Xunit;
using static Gremlin.Net.Process.Traversal.AnonymousTraversalSource;
@@ -46,6 +46,8 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
private readonly IDictionary<string, object> _parameters = new Dictionary<string, object>();
private ITraversal _traversal;
private object[] _result;
+ private static readonly JsonSerializerOptions JsonDeserializingOptions = new JsonSerializerOptions
+ {PropertyNamingPolicy = JsonNamingPolicy.CamelCase};
private static readonly IDictionary<Regex, Func<string, string, object>> Parsers =
new Dictionary<string, Func<string, string, object>>
@@ -234,7 +236,8 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
private static object ToMap(string stringMap, string graphName)
{
- return ParseMapValue(JObject.Parse(stringMap), graphName);
+ var jsonMap = JsonSerializer.Deserialize<JsonElement>(stringMap, JsonDeserializingOptions);
+ return ParseMapValue(jsonMap, graphName);
}
private static object ToLambda(string stringLambda, string graphName)
@@ -258,29 +261,45 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
stringNumber.Substring(0, stringNumber.Length - 1));
}
- private static object ParseMapValue(JToken value, string graphName)
+ private static object ParseMapValue(JsonElement value, string graphName)
{
- if (value.Type == JTokenType.Object)
+ switch (value.ValueKind)
{
- IDictionary<string, JToken> jsonMap = (JObject)value;
- return jsonMap.ToDictionary(kv => ParseMapValue(kv.Key, graphName),
- kv => ParseMapValue(kv.Value, graphName));
- }
- if (value.Type == JTokenType.Array)
- {
- return value.Select(v => ParseMapValue(v, graphName)).ToArray();
- }
- var objValue = value.ToObject<object>();
- if (objValue is long longValue)
- {
- // JSON Numeric values converted to int64 by default
- return Convert.ToInt32(longValue);
- }
- if (objValue is string stringValue)
- {
- return ParseValue(stringValue, graphName);
+ case JsonValueKind.Object:
+ {
+ return value.EnumerateObject().ToDictionary(property => ParseValue(property.Name, graphName),
+ property => ParseMapValue(property.Value, graphName));
+ }
+ case JsonValueKind.Array:
+ return value.EnumerateArray().Select(v => ParseMapValue(v, graphName)).ToArray();
+ case JsonValueKind.Number:
+ {
+ // This can maybe be simplified when this issue is resolved:
+ // https://github.com/dotnet/runtime/issues/31274
+ if (value.TryGetInt32(out var integer))
+ {
+ return integer;
+ }
+
+ if (value.TryGetDouble(out var floating))
+ {
+ return floating;
+ }
+
+ throw new ArgumentOutOfRangeException(nameof(value), value, "Not a supported number type");
+ }
+ case JsonValueKind.String:
+ return ParseValue(value.GetString(), graphName);
+ case JsonValueKind.True:
+ return true;
+ case JsonValueKind.False:
+ return false;
+ case JsonValueKind.Null:
+ return null;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(value.ValueKind), value.ValueKind,
+ "JSON type not supported");
}
- return objValue;
}
private static ISet<object> ToSet(string stringSet, string graphName)
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/JsonMessageSerializerTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/JsonMessageSerializerTests.cs
index 67766a5..79c1731 100644
--- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/JsonMessageSerializerTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/JsonMessageSerializerTests.cs
@@ -23,15 +23,12 @@
using Gremlin.Net.Driver;
using Gremlin.Net.Driver.Messages;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
using System;
using System.Text;
using Xunit;
namespace Gremlin.Net.UnitTest.Driver
{
- // Will be used in future to switch to new .NET Core Json deserializer
public class JsonMessageSerializerTests
{
[Fact]
@@ -39,7 +36,7 @@ namespace Gremlin.Net.UnitTest.Driver
{
var sut = new JsonMessageSerializer(GremlinClient.DefaultMimeType);
- Assert.Throws<ArgumentNullException>(()=> sut.DeserializeMessage<ResponseMessage<JToken>>(null));
+ Assert.Throws<ArgumentNullException>(()=> sut.DeserializeMessage<ResponseMessage>(null));
}
[Fact]
@@ -47,7 +44,7 @@ namespace Gremlin.Net.UnitTest.Driver
{
var sut = new JsonMessageSerializer(GremlinClient.DefaultMimeType);
- Assert.Null(sut.DeserializeMessage<ResponseMessage<JToken>>(new byte[0]));
+ Assert.Null(sut.DeserializeMessage<ResponseMessage>(new byte[0]));
}
[Fact]
@@ -56,7 +53,7 @@ namespace Gremlin.Net.UnitTest.Driver
var sut = new JsonMessageSerializer(GremlinClient.DefaultMimeType);
var ofEmpty = Encoding.UTF8.GetBytes("");
- Assert.Null(sut.DeserializeMessage<ResponseMessage<JToken>>(ofEmpty));
+ Assert.Null(sut.DeserializeMessage<ResponseMessage>(ofEmpty));
}
[Fact]
@@ -65,7 +62,7 @@ namespace Gremlin.Net.UnitTest.Driver
var sut = new JsonMessageSerializer(GremlinClient.DefaultMimeType);
var ofNull = Encoding.UTF8.GetBytes("null");
- Assert.Null(sut.DeserializeMessage<ResponseMessage<JToken>>(ofNull));
+ Assert.Null(sut.DeserializeMessage<ResponseMessage>(ofNull));
}
}
}
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj
index 415072f..90296be 100644
--- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj
@@ -12,7 +12,6 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="Moq" Version="4.7.99" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs
index 11b92fe..d50da9c 100644
--- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs
@@ -24,11 +24,11 @@
using System;
using System.Collections.Generic;
using System.Numerics;
+using System.Text.Json;
using Gremlin.Net.Process.Traversal;
using Gremlin.Net.Structure;
using Gremlin.Net.Structure.IO.GraphSON;
using Moq;
-using Newtonsoft.Json.Linq;
using Xunit;
namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
@@ -61,17 +61,6 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
return new GraphSON2Reader();
}
- //During CI, we encountered a case where Newtonsoft.Json version 9.0.0
- //was loaded although there is no obvious direct nor indirect dependency
- //on that version of the library. An explicit reference to version
- //11.0.0 from Gremlin.Net.UnitTest fixes that, however, it is
- //still unclear what causes the downgrade. Until resolution, we keep this test.
- [Fact]
- public void NewtonsoftJsonVersionShouldSupportReallyBigIntegers()
- {
- Assert.Equal(new Version(11, 0, 0, 0), typeof(JToken).Assembly.GetName().Version);
- }
-
[Fact]
public void ShouldDeserializeWithCustomDeserializerForNewType()
{
@@ -80,260 +69,297 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
{"NS:TestClass", new TestGraphSONDeserializer()}
};
var reader = new GraphSON2Reader(deserializerByGraphSONType);
- var graphSON = "{\"@type\":\"NS:TestClass\",\"@value\":\"test\"}";
-
- var jObject = JObject.Parse(graphSON);
- var readObj = reader.ToObject(jObject);
-
- Assert.Equal("test", readObj.Value);
- }
-
+ const string graphSON = "{\"@type\":\"NS:TestClass\",\"@value\":\"test\"}";
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSON);
+ var deserializedValue = reader.ToObject(jsonElement);
+
+ Assert.Equal("test", deserializedValue.Value);
+ }
+
[Fact]
public void ShouldDeserializeWithCustomDeserializerForCommonType()
{
var customSerializerMock = new Mock<IGraphSONDeserializer>();
- var overrideTypeString = "g:Int64";
+ const string overrideTypeString = "g:Int64";
var customSerializerByType = new Dictionary<string, IGraphSONDeserializer>
{
{overrideTypeString, customSerializerMock.Object}
};
var reader = new GraphSON2Reader(customSerializerByType);
+ var jsonElement =
+ JsonSerializer.Deserialize<JsonElement>($"{{\"@type\":\"{overrideTypeString}\",\"@value\":12}}");
+ var deserializedValue = reader.ToObject(jsonElement);
- reader.ToObject(JObject.Parse($"{{\"@type\":\"{overrideTypeString}\",\"@value\":12}}"));
-
- customSerializerMock.Verify(m => m.Objectify(It.IsAny<JToken>(), It.IsAny<GraphSONReader>()));
+ customSerializerMock.Verify(m => m.Objectify(It.IsAny<JsonElement>(), It.IsAny<GraphSONReader>()));
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeDateToDateTimeOffset(int version)
{
- var graphSon = "{\"@type\":\"g:Date\",\"@value\":1475583442552}";
+ const string graphSon = "{\"@type\":\"g:Date\",\"@value\":1475583442552}";
var reader = CreateStandardGraphSONReader(version);
-
- DateTimeOffset deserializedValue = reader.ToObject(JObject.Parse(graphSon));
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ var deserializedValue = reader.ToObject(jsonElement);
+
var expectedDateTimeOffset = TestUtils.FromJavaTime(1475583442552);
Assert.Equal(expectedDateTimeOffset, deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeDictionary(int version)
{
- var serializedDict = "{\"age\":[{\"@type\":\"g:Int32\",\"@value\":29}],\"name\":[\"marko\"],\"gender\": null}";
+ const string serializedDict = "{\"age\":[{\"@type\":\"g:Int32\", \"@value\":29}], \"name\":[\"marko\"], " +
+ "\"gender\": null}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedDict);
- var deserializedDict = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(serializedDict);
+ var deserializedValue = reader.ToObject(jsonElement);
+
var expectedDict = new Dictionary<string, dynamic>
{
{"age", new List<object> {29}},
{"name", new List<object> {"marko"}},
{"gender", null}
};
- Assert.Equal(expectedDict, deserializedDict);
+ Assert.Equal(expectedDict, deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeEdge(int version)
{
- var graphSon =
- "{\"@type\":\"g:Edge\", \"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":17},\"label\":\"knows\",\"inV\":\"x\",\"outV\":\"y\",\"inVLabel\":\"xLab\",\"properties\":{\"aKey\":\"aValue\",\"bKey\":true}}}";
+ const string graphSon = "{\"@type\":\"g:Edge\", \"@value\":{\"id\":{\"@type\":\"g:Int64\", \"@value\":17}, " +
+ "\"label\":\"knows\", \"inV\":\"x\", \"outV\":\"y\", \"inVLabel\":\"xLab\", " +
+ "\"properties\":{\"aKey\":\"aValue\", \"bKey\":true}}}";
var reader = CreateStandardGraphSONReader(version);
-
- Edge readEdge = reader.ToObject(JObject.Parse(graphSon));
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ Edge readEdge = reader.ToObject(jsonElement);
+
Assert.Equal((long) 17, readEdge.Id);
Assert.Equal("knows", readEdge.Label);
Assert.Equal(new Vertex("x", "xLabel"), readEdge.InV);
Assert.Equal(new Vertex("y"), readEdge.OutV);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeInt(int version)
{
var serializedValue = "{\"@type\":\"g:Int32\",\"@value\":5}";
var reader = CreateStandardGraphSONReader(version);
- var jObject = JObject.Parse(serializedValue);
- var deserializedValue = reader.ToObject(jObject);
-
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(serializedValue);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(5, deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeLong(int version)
{
- var serializedValue = "{\"@type\":\"g:Int64\",\"@value\":5}";
+ const string serializedValue = "{\"@type\":\"g:Int64\",\"@value\":5}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- var deserializedValue = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(serializedValue);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal((long) 5, deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeFloat(int version)
{
- var serializedValue = "{\"@type\":\"g:Float\",\"@value\":31.3}";
+ const string serializedValue = "{\"@type\":\"g:Float\",\"@value\":31.3}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- var deserializedValue = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(serializedValue);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal((float) 31.3, deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeDouble(int version)
{
- var serializedValue = "{\"@type\":\"g:Double\",\"@value\":31.2}";
+ const string serializedValue = "{\"@type\":\"g:Double\",\"@value\":31.2}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- var deserializedValue = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(serializedValue);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(31.2, deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeNaN(int version)
{
- var serializedValue = "{\"@type\":\"g:Double\",\"@value\":'NaN'}";
+ const string serializedValue = "{\"@type\":\"g:Double\",\"@value\":\"NaN\"}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- var deserializedValue = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(serializedValue);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(Double.NaN, deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializePositiveInfinity(int version)
{
- var serializedValue = "{\"@type\":\"g:Double\",\"@value\":'Infinity'}";
+ const string serializedValue = "{\"@type\":\"g:Double\",\"@value\":\"Infinity\"}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- var deserializedValue = reader.ToObject(jObject);
-
- Assert.Equal(Double.PositiveInfinity, deserializedValue);
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(serializedValue);
+ var deserializedValue = reader.ToObject(jsonElement);
+
+ Assert.Equal(double.PositiveInfinity, deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeNegativeInfinity(int version)
{
- var serializedValue = "{\"@type\":\"g:Double\",\"@value\":'-Infinity'}";
+ const string serializedValue = "{\"@type\":\"g:Double\",\"@value\":\"-Infinity\"}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- var deserializedValue = reader.ToObject(jObject);
-
- Assert.Equal(Double.NegativeInfinity, deserializedValue);
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(serializedValue);
+ var deserializedValue = reader.ToObject(jsonElement);
+
+ Assert.Equal(double.NegativeInfinity, deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeDecimal(int version)
{
- var serializedValue = "{\"@type\":\"gx:BigDecimal\",\"@value\":-8.201}";
+ const string serializedValue = "{\"@type\":\"gx:BigDecimal\",\"@value\":-8.201}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- decimal deserializedValue = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(serializedValue);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(-8.201M, deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeDecimalValueAsString(int version)
{
- var serializedValue = "{\"@type\":\"gx:BigDecimal\",\"@value\":\"7.50\"}";
+ const string serializedValue = "{\"@type\":\"gx:BigDecimal\",\"@value\":\"7.50\"}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- decimal deserializedValue = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(serializedValue);
+ decimal deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(7.5M, deserializedValue);
}
-
+
+ [Theory, MemberData(nameof(Versions))]
+ public void ShouldDeserializeByte(int version)
+ {
+ const string serializedValue = "{\"@type\":\"gx:Byte\",\"@value\":1}";
+ var reader = CreateStandardGraphSONReader(version);
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(serializedValue);
+ var deserializedValue = reader.ToObject(jsonElement);
+
+ Assert.Equal(1, deserializedValue);
+ }
+
+ [Theory, MemberData(nameof(Versions))]
+ public void ShouldDeserializeChar(int version)
+ {
+ const string serializedValue = "{\"@type\":\"gx:Char\",\"@value\":\"x\"}";
+ var reader = CreateStandardGraphSONReader(version);
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(serializedValue);
+ var deserializedValue = reader.ToObject(jsonElement);
+
+ Assert.Equal('x', deserializedValue);
+ }
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeList(int version)
{
- var serializedValue = "[{\"@type\":\"g:Int32\",\"@value\":5},{\"@type\":\"g:Int32\",\"@value\":6},null]";
+ const string serializedValue = "[{\"@type\":\"g:Int32\", \"@value\":5}, {\"@type\":\"g:Int32\", " +
+ "\"@value\":6}, null]";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JArray.Parse(serializedValue);
- var deserializedValue = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(serializedValue);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(new List<object> {5, 6, null}, deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeT(int version)
{
- var graphSon = "{\"@type\":\"g:T\",\"@value\":\"label\"}";
+ const string graphSon = "{\"@type\":\"g:T\",\"@value\":\"label\"}";
var reader = CreateStandardGraphSONReader(version);
-
- T readT = reader.ToObject(JObject.Parse(graphSon));
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ T readT = reader.ToObject(jsonElement);
+
Assert.Equal(T.Label, readT);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeDirection(int version)
{
- var serializedValue = "{\"@type\":\"g:Direction\",\"@value\":\"OUT\"}";
+ const string serializedValue = "{\"@type\":\"g:Direction\",\"@value\":\"OUT\"}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- var deserializedValue = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(serializedValue);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(Direction.Out, deserializedValue);
}
-
+
[Fact]
public void ShouldDeserializePathFromGraphSON2()
{
- var graphSon =
+ const string graphSon =
"{\"@type\":\"g:Path\",\"@value\":{\"labels\":[[\"a\"],[\"b\",\"c\"],[]],\"objects\":[{\"@type\":\"g:Vertex\",\"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":1},\"label\":\"person\",\"properties\":{\"name\":[{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":0},\"value\":\"marko\",\"label\":\"name\"}}],\"age\":[{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":1},\"value\":{\"@type\":\"g:Int32\",\"@ [...]
var reader = CreateStandardGraphSONReader(2);
-
- Path readPath = reader.ToObject(JObject.Parse(graphSon));
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ Path readPath = reader.ToObject(jsonElement);
+
Assert.Equal("path[v[1], v[3], lop]", readPath.ToString());
Assert.Equal(new Vertex(1), readPath[0]);
Assert.Equal(new Vertex(1), readPath["a"]);
Assert.Equal("lop", readPath[2]);
Assert.Equal(3, readPath.Count);
}
-
+
[Fact]
public void ShouldDeserializePathFromGraphSON3()
{
- var graphSon = "{\"@type\":\"g:Path\",\"@value\":{" +
- "\"labels\":{\"@type\":\"g:List\",\"@value\":[{\"@type\":\"g:Set\",\"@value\":[\"z\"]}]}," +
- "\"objects\":{\"@type\":\"g:List\",\"@value\":[{\"@type\":\"g:Vertex\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":5},\"label\":\"\"}}]}}}";
+ const string graphSon = "{\"@type\":\"g:Path\",\"@value\":{" +
+ "\"labels\":{\"@type\":\"g:List\",\"@value\":[{\"@type\":\"g:Set\",\"@value\":[\"z\"]}]}," +
+ "\"objects\":{\"@type\":\"g:List\",\"@value\":[{\"@type\":\"g:Vertex\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":5},\"label\":\"\"}}]}}}";
var reader = CreateStandardGraphSONReader(3);
-
- Path readPath = reader.ToObject(JObject.Parse(graphSon));
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ Path readPath = reader.ToObject(jsonElement);
+
Assert.Equal("path[v[5]]", readPath.ToString());
Assert.Equal(new Vertex(5L), readPath[0]);
Assert.Equal(new Vertex(5L), readPath["z"]);
Assert.Equal(1, readPath.Count);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializePropertyWithEdgeElement(int version)
{
- var graphSon =
- "{\"@type\":\"g:Property\",\"@value\":{\"key\":\"aKey\",\"value\":{\"@type\":\"g:Int64\",\"@value\":17},\"element\":{\"@type\":\"g:Edge\",\"@value\":{\"id\":{\"@type\":\"g:Int64\",\"@value\":122},\"label\":\"knows\",\"inV\":\"x\",\"outV\":\"y\",\"inVLabel\":\"xLab\"}}}}";
+ const string graphSon = "{\"@type\":\"g:Property\", \"@value\":{\"key\":\"aKey\", " +
+ "\"value\":{\"@type\":\"g:Int64\", \"@value\":17}, " +
+ "\"element\":{\"@type\":\"g:Edge\", \"@value\":{\"id\":{\"@type\":\"g:Int64\", " +
+ "\"@value\":122}, \"label\":\"knows\", \"inV\":\"x\", \"outV\":\"y\", " +
+ "\"inVLabel\":\"xLab\"}}}}";
var reader = CreateStandardGraphSONReader(version);
-
- Property readProperty = reader.ToObject(JObject.Parse(graphSon));
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ Property readProperty = reader.ToObject(jsonElement);
+
Assert.Equal("aKey", readProperty.Key);
Assert.Equal((long) 17, readProperty.Value);
Assert.Equal(typeof(Edge), readProperty.Element.GetType());
@@ -343,265 +369,285 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
Assert.Equal("x", edge.InV.Id);
Assert.Equal("y", edge.OutV.Id);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeTimestampToDateTimeOffset(int version)
{
- var graphSon = "{\"@type\":\"g:Timestamp\",\"@value\":1475583442558}";
+ const string graphSon = "{\"@type\":\"g:Timestamp\",\"@value\":1475583442558}";
var reader = CreateStandardGraphSONReader(version);
-
- DateTimeOffset deserializedValue = reader.ToObject(JObject.Parse(graphSon));
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ var deserializedValue = reader.ToObject(jsonElement);
+
var expectedDateTimeOffset = TestUtils.FromJavaTime(1475583442558);
Assert.Equal(expectedDateTimeOffset, deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeGuid(int version)
{
- var graphSon = "{\"@type\":\"g:UUID\",\"@value\":\"41d2e28a-20a4-4ab0-b379-d810dede3786\"}";
+ const string graphSon = "{\"@type\":\"g:UUID\",\"@value\":\"41d2e28a-20a4-4ab0-b379-d810dede3786\"}";
var reader = CreateStandardGraphSONReader(version);
-
- Guid readGuid = reader.ToObject(JObject.Parse(graphSon));
-
- Assert.Equal(Guid.Parse("41d2e28a-20a4-4ab0-b379-d810dede3786"), readGuid);
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ var deserializedValue = reader.ToObject(jsonElement);
+
+ Assert.Equal(Guid.Parse("41d2e28a-20a4-4ab0-b379-d810dede3786"), deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeVertexProperty(int version)
{
- var graphSon =
- "{\"@type\":\"g:VertexProperty\",\"@value\":{\"id\":\"anId\",\"label\":\"aKey\",\"value\":true,\"vertex\":{\"@type\":\"g:Int32\",\"@value\":9}}}";
+ const string graphSon = "{\"@type\":\"g:VertexProperty\", \"@value\":{\"id\":\"anId\", \"label\":\"aKey\", " +
+ "\"value\":true, \"vertex\":{\"@type\":\"g:Int32\", \"@value\":9}}}";
var reader = CreateStandardGraphSONReader(version);
-
- VertexProperty readVertexProperty = reader.ToObject(JObject.Parse(graphSon));
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ VertexProperty readVertexProperty = reader.ToObject(jsonElement);
+
Assert.Equal("anId", readVertexProperty.Id);
Assert.Equal("aKey", readVertexProperty.Label);
Assert.True(readVertexProperty.Value);
Assert.NotNull(readVertexProperty.Vertex);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeVertexPropertyWithLabel(int version)
{
- var graphSon =
- "{\"@type\":\"g:VertexProperty\", \"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":1},\"label\":\"name\",\"value\":\"marko\"}}";
+ const string graphSon = "{\"@type\":\"g:VertexProperty\", \"@value\":{\"id\":{\"@type\":\"g:Int32\", " +
+ "\"@value\":1}, \"label\":\"name\", \"value\":\"marko\"}}";
var reader = CreateStandardGraphSONReader(version);
-
- VertexProperty readVertexProperty = reader.ToObject(JObject.Parse(graphSon));
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ VertexProperty readVertexProperty = reader.ToObject(jsonElement);
+
Assert.Equal(1, readVertexProperty.Id);
Assert.Equal("name", readVertexProperty.Label);
Assert.Equal("marko", readVertexProperty.Value);
Assert.Null(readVertexProperty.Vertex);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeVertex(int version)
{
- var graphSon = "{\"@type\":\"g:Vertex\", \"@value\":{\"id\":{\"@type\":\"g:Float\",\"@value\":45.23}}}";
+ const string graphSon = "{\"@type\":\"g:Vertex\", \"@value\":{\"id\":{\"@type\":\"g:Float\", " +
+ "\"@value\":45.23}}}";
var reader = CreateStandardGraphSONReader(version);
-
- var readVertex = reader.ToObject(JObject.Parse(graphSon));
-
- Assert.Equal(new Vertex(45.23f), readVertex);
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ var deserializedValue = reader.ToObject(jsonElement);
+
+ Assert.Equal(new Vertex(45.23f), deserializedValue);
}
-
+
+ [Theory, MemberData(nameof(Versions))]
+ public void ShouldDeserializeVertexWithLabel(int version)
+ {
+ const string graphSon = "{\"@type\":\"g:Vertex\", \"@value\":{\"id\":{\"@type\":\"g:Float\", " +
+ "\"@value\":45.23}, \"label\": \"person\"}}";
+ var reader = CreateStandardGraphSONReader(version);
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ Vertex deserializedValue = reader.ToObject(jsonElement);
+
+ Assert.Equal("person", deserializedValue.Label);
+ }
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeVertexWithEdges(int version)
{
- var graphSon =
+ const string graphSon =
"{\"@type\":\"g:Vertex\", \"@value\":{\"id\":{\"@type\":\"g:Int32\",\"@value\":1},\"label\":\"person\",\"outE\":{\"created\":[{\"id\":{\"@type\":\"g:Int32\",\"@value\":9},\"inV\":{\"@type\":\"g:Int32\",\"@value\":3},\"properties\":{\"weight\":{\"@type\":\"g:Double\",\"@value\":0.4}}}],\"knows\":[{\"id\":{\"@type\":\"g:Int32\",\"@value\":7},\"inV\":{\"@type\":\"g:Int32\",\"@value\":2},\"properties\":{\"weight\":{\"@type\":\"g:Double\",\"@value\":0.5}}},{\"id\":{\"@type\":\ [...]
var reader = CreateStandardGraphSONReader(version);
-
- var readVertex = reader.ToObject(JObject.Parse(graphSon));
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ Vertex readVertex = reader.ToObject(jsonElement);
+
Assert.Equal(new Vertex(1), readVertex);
Assert.Equal("person", readVertex.Label);
Assert.Equal(typeof(int), readVertex.Id.GetType());
}
-
+
[Theory, MemberData(nameof(VersionsSupportingCollections))]
public void ShouldDeserializeEmptyGList(int version)
{
- var graphSon =
- "{\"@type\":\"g:List\", \"@value\": []}";
+ const string graphSon = "{\"@type\":\"g:List\", \"@value\": []}";
var reader = CreateStandardGraphSONReader(version);
-
- var deserializedValue = reader.ToObject(JObject.Parse(graphSon));
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(new object[0], deserializedValue);
}
-
+
[Theory, MemberData(nameof(VersionsSupportingCollections))]
public void ShouldDeserializeGList(int version)
{
const string json = "{\"@type\":\"g:List\", \"@value\": [{\"@type\": \"g:Int32\", \"@value\": 1}," +
"{\"@type\": \"g:Int32\", \"@value\": 2}, {\"@type\": \"g:Int32\", \"@value\": 3}]}";
var reader = CreateStandardGraphSONReader(version);
-
- var deserializedValue = reader.ToObject(JObject.Parse(json));
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal((IList<object>)new object[] { 1, 2, 3}, deserializedValue);
}
-
+
[Theory, MemberData(nameof(VersionsSupportingCollections))]
public void ShouldDeserializeGSet(int version)
{
- const string json = "{\"@type\":\"g:Set\", \"@value\": [{\"@type\": \"g:Int32\", \"@value\": 1}," +
- "{\"@type\": \"g:Int32\", \"@value\": 2}, {\"@type\": \"g:Int32\", \"@value\": 3}]}";
+ const string graphSon = "{\"@type\":\"g:Set\", \"@value\": [{\"@type\": \"g:Int32\", \"@value\": 1}," +
+ "{\"@type\": \"g:Int32\", \"@value\": 2}, {\"@type\": \"g:Int32\", \"@value\": 3}]}";
var reader = CreateStandardGraphSONReader(version);
-
- var deserializedValue = reader.ToObject(JObject.Parse(json));
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal((ISet<object>)new HashSet<object>{ 1, 2, 3}, deserializedValue);
}
-
+
[Theory, MemberData(nameof(VersionsSupportingCollections))]
public void ShouldDeserializeGMap(int version)
{
const string json = "{\"@type\":\"g:Map\", \"@value\": [\"a\",{\"@type\": \"g:Int32\", \"@value\": 1}, " +
"\"b\", {\"@type\": \"g:Int32\", \"@value\": 2}]}";
var reader = CreateStandardGraphSONReader(version);
-
- var deserializedValue = reader.ToObject(JObject.Parse(json));
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(new Dictionary<object, object>{ { "a", 1 }, { "b", 2 }}, deserializedValue);
}
-
+
+ [Theory, MemberData(nameof(VersionsSupportingCollections))]
+ public void ShouldDeserializeGMapWithNonStringKeys(int version)
+ {
+ const string json = "{\"@type\":\"g:Map\", \"@value\": [{\"@type\":\"g:Int32\", \"@value\":123}, \"red\"]}";
+ var reader = CreateStandardGraphSONReader(version);
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
+ var deserializedValue = reader.ToObject(jsonElement);
+
+ Assert.Equal(new Dictionary<object, object>{ { 123, "red" }}, deserializedValue);
+ }
+
[Theory, MemberData(nameof(VersionsSupportingCollections))]
public void ShouldDeserializeBulkSet(int version)
{
- const string json = "{\"@type\": \"g:BulkSet\", \"@value\": [" +
- "\"marko\", {\"@type\": \"g:Int64\", \"@value\": 1}, " +
- "\"josh\", {\"@type\": \"g:Int64\", \"@value\": 3}]}";
+ const string graphSon = "{\"@type\": \"g:BulkSet\", \"@value\": [" +
+ "\"marko\", {\"@type\": \"g:Int64\", \"@value\": 1}, " +
+ "\"josh\", {\"@type\": \"g:Int64\", \"@value\": 3}]}";
var reader = CreateStandardGraphSONReader(version);
-
- var deserializedValue = reader.ToObject(JObject.Parse(json));
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(new List<object>{ "marko", "josh", "josh", "josh" }, deserializedValue);
}
-
+
[Fact]
public void ShouldDeserializeBulkSetWithGraphSON3()
{
- const string json =
+ const string graphSon =
"{\"@type\":\"g:List\",\"@value\":[{\"@type\":\"g:Traverser\",\"@value\":{\"bulk\":{\"@type\":\"g:Int64\",\"@value\":1},\"value\":{\"@type\":\"g:BulkSet\",\"@value\":[{\"@type\":\"g:Int64\",\"@value\":1},{\"@type\":\"g:Int64\",\"@value\":2},{\"@type\":\"g:Int64\",\"@value\":0},{\"@type\":\"g:Int64\",\"@value\":3},{\"@type\":\"g:Int64\",\"@value\":2},{\"@type\":\"g:Int64\",\"@value\":1},{\"@type\":\"g:Double\",\"@value\":1.0},{\"@type\":\"g:Int64\",\"@value\":2}]}}}]}";
var reader = CreateStandardGraphSONReader(3);
- var deserializedValue = reader.ToObject(JObject.Parse(json));
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ var deserializedValue = reader.ToObject(jsonElement);
}
-
- [Fact]
- public void ShouldDeserializeTraverser()
+
+ [Theory, MemberData(nameof(VersionsSupportingCollections))]
+ public void ShouldDeserializeTraverser(int version)
{
- dynamic d = JObject.Parse("{\"@type\":\"g:Traverser\",\"@value\":1,\"bulk\": {\"type\":\"g:Int64\",\"value\":10}}");
-
- Assert.NotNull(d);
- Assert.Equal("g:Traverser", (string)d["@type"]);
+ const string json = "{\"@type\":\"g:Traverser\", \"@value\":{\"bulk\":{\"@type\":\"g:Int64\", " +
+ "\"@value\":10}, \"value\":{\"@type\":\"g:Int32\", \"@value\":1}}}";
+ var reader = CreateStandardGraphSONReader(version);
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
+ Traverser deserializedValue = reader.ToObject(jsonElement);
+
+ Assert.Equal(10, deserializedValue.Bulk);
+ Assert.Equal(1, deserializedValue.Object);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeDurationToTimeSpan(int version)
{
- var serializedValue = "{\"@type\":\"gx:Duration\",\"@value\":\"PT120H\"}";
+ const string graphSon = "{\"@type\":\"gx:Duration\",\"@value\":\"PT120H\"}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- TimeSpan deserializedValue = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(TimeSpan.FromDays(5), deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeBigInteger(int version)
{
- var serializedValue = "{\"@type\":\"gx:BigInteger\",\"@value\":123456789}";
+ var graphSon = "{\"@type\":\"gx:BigInteger\",\"@value\":123456789}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- BigInteger deserializedValue = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(BigInteger.Parse("123456789"), deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeBigIntegerValueAsString(int version)
{
- var serializedValue = "{\"@type\":\"gx:BigInteger\",\"@value\":\"123456789\"}";
+ var graphSon = "{\"@type\":\"gx:BigInteger\", \"@value\":\"123456789\"}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- BigInteger deserializedValue = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(BigInteger.Parse("123456789"), deserializedValue);
}
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeReallyBigIntegerValue(int version)
{
- var serializedValue = "{\"@type\":\"gx:BigInteger\",\"@value\":123456789987654321123456789987654321}";
+ const string graphSon = "{\"@type\":\"gx:BigInteger\", \"@value\":123456789987654321123456789987654321}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- BigInteger deserializedValue = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(BigInteger.Parse("123456789987654321123456789987654321"), deserializedValue);
}
-
- [Theory, MemberData(nameof(Versions))]
- public void ShouldDeserializeByte(int version)
- {
- var serializedValue = "{\"@type\":\"gx:Byte\",\"@value\":1}";
- var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- var deserializedValue = reader.ToObject(jObject);
-
- Assert.Equal(1, deserializedValue);
- }
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeByteBuffer(int version)
{
- var serializedValue = "{\"@type\":\"gx:ByteBuffer\",\"@value\":\"c29tZSBieXRlcyBmb3IgeW91\"}";
+ const string graphSon = "{\"@type\":\"gx:ByteBuffer\", \"@value\":\"c29tZSBieXRlcyBmb3IgeW91\"}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- var deserializedValue = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(Convert.FromBase64String("c29tZSBieXRlcyBmb3IgeW91"), deserializedValue);
}
-
- [Theory, MemberData(nameof(Versions))]
- public void ShouldDeserializeChar(int version)
- {
- var serializedValue = "{\"@type\":\"gx:Char\",\"@value\":\"x\"}";
- var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- var deserializedValue = reader.ToObject(jObject);
-
- Assert.Equal('x', deserializedValue);
- }
-
+
[Theory, MemberData(nameof(Versions))]
public void ShouldDeserializeInt16(int version)
{
- var serializedValue = "{\"@type\":\"gx:Int16\",\"@value\":100}";
+ const string graphSon = "{\"@type\":\"gx:Int16\", \"@value\":100}";
var reader = CreateStandardGraphSONReader(version);
-
- var jObject = JObject.Parse(serializedValue);
- var deserializedValue = reader.ToObject(jObject);
-
+
+ var jsonElement = JsonSerializer.Deserialize<JsonElement>(graphSon);
+ var deserializedValue = reader.ToObject(jsonElement);
+
Assert.Equal(100, deserializedValue);
}
}
internal class TestGraphSONDeserializer : IGraphSONDeserializer
{
- public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
+ public dynamic Objectify(JsonElement graphsonObject, GraphSONReader reader)
{
- return new TestClass {Value = graphsonObject.ToString()};
+ return new TestClass {Value = graphsonObject.GetString()};
}
}
}
\ No newline at end of file
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
index 2eb7d51..ce593f7 100644
--- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
@@ -203,6 +203,8 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
public void ShouldSerializeWithCustomSerializerForCommonType()
{
var customSerializerMock = new Mock<IGraphSONSerializer>();
+ customSerializerMock.Setup(m => m.Dictify(It.IsAny<int>(), It.IsAny<GraphSONWriter>()))
+ .Returns(new Dictionary<string, dynamic>());
var customSerializerByType = new Dictionary<Type, IGraphSONSerializer>
{
{typeof(int), customSerializerMock.Object}