From 65193ef5e8503864bc5837eaeb2fad800adac178 Mon Sep 17 00:00:00 2001 From: Loic Denuziere Date: Mon, 9 Jun 2025 10:36:36 +0200 Subject: [PATCH 1/2] feat: use ListCollector to build lists --- .../Program.fs | 37 ++- paket.dependencies | 4 +- paket.lock | 308 +++++++++--------- src/FSharp.SystemTextJson/Collection.fs | 14 +- 4 files changed, 195 insertions(+), 168 deletions(-) diff --git a/benchmarks/FSharp.SystemTextJson.Benchmarks/Program.fs b/benchmarks/FSharp.SystemTextJson.Benchmarks/Program.fs index b4159f1..4005c96 100644 --- a/benchmarks/FSharp.SystemTextJson.Benchmarks/Program.fs +++ b/benchmarks/FSharp.SystemTextJson.Benchmarks/Program.fs @@ -6,23 +6,15 @@ open System open BenchmarkDotNet.Attributes open BenchmarkDotNet.Diagnosers open BenchmarkDotNet.Configs -open BenchmarkDotNet.Jobs open BenchmarkDotNet.Running open BenchmarkDotNet.Validators open BenchmarkDotNet.Exporters -open BenchmarkDotNet.Environments -open System.Reflection -open BenchmarkDotNet.Configs open System.Text.Json open System.Text.Json.Serialization open Newtonsoft.Json -open Newtonsoft.Json.Linq -type TestRecord = - { name: string - thing: bool option - time: System.DateTimeOffset } +type TestRecord = { name: string; thing: bool option; time: DateTimeOffset } type SimpleClass() = member val Name: string = null with get, set @@ -119,6 +111,30 @@ type TupleComparison() = member this.RefSpecialized() = System.Text.Json.JsonSerializer.Deserialize("[1,true]", specializedOptions) +type ListDeserialization<'t>(instance: 't) = + let options = JsonFSharpOptions().ToJsonSerializerOptions() + + [] + member val ListLength = 0 with get, set + + member val String = "" with get, set + + [] + member this.InitList() = + this.String <- System.Text.Json.JsonSerializer.Serialize(Array.replicate this.ListLength instance, options) + + [] + member this.ListCollector() = + System.Text.Json.JsonSerializer.Deserialize<'t list>(this.String, options) + + [] + member this.AsArray() = + System.Text.Json.JsonSerializer.Deserialize<'t array>(this.String, options) + |> List.ofArray + +type ListDeserialization() = + inherit ListDeserialization(42) + let config = ManualConfig .Create(DefaultConfig.Instance) @@ -131,7 +147,8 @@ let defaultSwitch () = [| typeof typeof typeof - typeof |] + typeof + typeof |] ) diff --git a/paket.dependencies b/paket.dependencies index 923d5af..0cb2b72 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -2,7 +2,7 @@ frameworks netstandard2.0 storage none source https://api.nuget.org/v3/index.json -nuget FSharp.Core >= 4.7.0 lowest_matching:true +nuget FSharp.Core >= 6.0 lowest_matching:true nuget Microsoft.SourceLink.GitHub prerelease copy_local:true nuget Nerdbank.GitVersioning copy_local:true nuget System.Text.Json >= 6.0.10 lowest_matching: true @@ -12,7 +12,7 @@ framework net9.0 storage none source https://api.nuget.org/v3/index.json -nuget FSharp.Core >= 5.0 +nuget FSharp.Core >= 6.0 nuget FsCheck.XUnit nuget Microsoft.NET.Test.Sdk nuget System.Text.Json >= 8.0.5 prerelease diff --git a/paket.lock b/paket.lock index 3519282..6778b5e 100644 --- a/paket.lock +++ b/paket.lock @@ -2,23 +2,23 @@ STORAGE: NONE RESTRICTION: == netstandard2.0 NUGET remote: https://api.nuget.org/v3/index.json - FSharp.Core (4.7) - Microsoft.Bcl.AsyncInterfaces (8.0) + FSharp.Core (6.0) + Microsoft.Bcl.AsyncInterfaces (9.0.5) System.Threading.Tasks.Extensions (>= 4.5.4) Microsoft.Build.Tasks.Git (8.0) - copy_local: true Microsoft.SourceLink.Common (8.0) - copy_local: true Microsoft.SourceLink.GitHub (8.0) - copy_local: true Microsoft.Build.Tasks.Git (>= 8.0) Microsoft.SourceLink.Common (>= 8.0) - Nerdbank.GitVersioning (3.6.133) - copy_local: true - System.Buffers (4.5.1) - System.Memory (4.5.5) - System.Buffers (>= 4.5.1) - System.Numerics.Vectors (>= 4.4) - System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - System.Numerics.Vectors (4.5) - System.Runtime.CompilerServices.Unsafe (6.0) - System.Text.Encodings.Web (8.0) + Nerdbank.GitVersioning (3.7.115) - copy_local: true + System.Buffers (4.6.1) + System.Memory (4.6.3) + System.Buffers (>= 4.6.1) + System.Numerics.Vectors (>= 4.6.1) + System.Runtime.CompilerServices.Unsafe (>= 6.1.2) + System.Numerics.Vectors (4.6.1) + System.Runtime.CompilerServices.Unsafe (6.1.2) + System.Text.Encodings.Web (9.0.5) System.Buffers (>= 4.5.1) System.Memory (>= 4.5.5) System.Runtime.CompilerServices.Unsafe (>= 6.0) @@ -30,8 +30,8 @@ NUGET System.Runtime.CompilerServices.Unsafe (>= 6.0) System.Text.Encodings.Web (>= 6.0) System.Threading.Tasks.Extensions (>= 4.5.4) - System.Threading.Tasks.Extensions (4.5.4) - System.Runtime.CompilerServices.Unsafe (>= 4.5.3) + System.Threading.Tasks.Extensions (4.6.3) + System.Runtime.CompilerServices.Unsafe (>= 6.1.2) GROUP fake STORAGE: NONE @@ -125,51 +125,52 @@ NUGET FSharp.Core (>= 8.0.301) FParsec (1.1.1) FSharp.Core (>= 4.3.4) - FSharp.Control.Reactive (5.0.5) - FSharp.Core (>= 4.7.2) - System.Reactive (>= 5.0 < 6.0) - FSharp.Core (9.0.100) - Microsoft.Build.Framework (17.12.6) - Microsoft.Build.Utilities.Core (17.12.6) - Microsoft.Build.Framework (>= 17.12.6) - Microsoft.NET.StringTools (>= 17.12.6) - System.Collections.Immutable (>= 8.0) - System.Configuration.ConfigurationManager (>= 8.0) - Microsoft.NET.StringTools (17.12.6) + FSharp.Control.Reactive (6.1.2) + FSharp.Core (>= 6.0.7) + System.Reactive (>= 6.0.1) + FSharp.Core (9.0.300) + Microsoft.Build.Framework (17.14.8) + Microsoft.Build.Utilities.Core (17.14.8) + Microsoft.Build.Framework (>= 17.14.8) + Microsoft.NET.StringTools (>= 17.14.8) + System.Collections.Immutable (>= 9.0) + System.Configuration.ConfigurationManager (>= 9.0) + System.Diagnostics.EventLog (>= 9.0) + System.Security.Cryptography.ProtectedData (>= 9.0) + Microsoft.NET.StringTools (17.14.8) Microsoft.Win32.Registry (5.0) System.Security.AccessControl (>= 5.0) System.Security.Principal.Windows (>= 5.0) Mono.Posix.NETStandard (1.0) - MSBuild.StructuredLogger (2.2.386) + MSBuild.StructuredLogger (2.2.472) Microsoft.Build.Framework (>= 17.5) Microsoft.Build.Utilities.Core (>= 17.5) System.Collections.Immutable (>= 8.0) Newtonsoft.Json (13.0.3) - NuGet.Common (6.12.1) - NuGet.Frameworks (>= 6.12.1) - NuGet.Configuration (6.12.1) - NuGet.Common (>= 6.12.1) + NuGet.Common (6.14) + NuGet.Frameworks (>= 6.14) + System.Collections.Immutable (>= 8.0) + NuGet.Configuration (6.14) + NuGet.Common (>= 6.14) System.Security.Cryptography.ProtectedData (>= 4.4) - NuGet.Frameworks (6.12.1) - NuGet.Packaging (6.12.1) + NuGet.Frameworks (6.14) + NuGet.Packaging (6.14) Newtonsoft.Json (>= 13.0.3) - NuGet.Configuration (>= 6.12.1) - NuGet.Versioning (>= 6.12.1) - System.Formats.Asn1 (>= 8.0.1) + NuGet.Configuration (>= 6.14) + NuGet.Versioning (>= 6.14) System.Security.Cryptography.Pkcs (>= 6.0.4) - NuGet.Protocol (6.12.1) - NuGet.Packaging (>= 6.12.1) - NuGet.Versioning (6.12.1) - System.Collections.Immutable (9.0) - System.Configuration.ConfigurationManager (9.0) - System.Diagnostics.EventLog (>= 9.0) - System.Security.Cryptography.ProtectedData (>= 9.0) - System.Diagnostics.EventLog (9.0) - System.Formats.Asn1 (9.0) - System.Reactive (5.0) + NuGet.Protocol (6.14) + NuGet.Packaging (>= 6.14) + NuGet.Versioning (6.14) + System.Collections.Immutable (9.0.5) + System.Configuration.ConfigurationManager (9.0.5) + System.Diagnostics.EventLog (>= 9.0.5) + System.Security.Cryptography.ProtectedData (>= 9.0.5) + System.Diagnostics.EventLog (9.0.5) + System.Reactive (6.0.1) System.Security.AccessControl (6.0.1) - System.Security.Cryptography.Pkcs (9.0) - System.Security.Cryptography.ProtectedData (9.0) + System.Security.Cryptography.Pkcs (9.0.5) + System.Security.Cryptography.ProtectedData (9.0.5) System.Security.Principal.Windows (5.0) GROUP test @@ -177,138 +178,139 @@ STORAGE: NONE RESTRICTION: == net9.0 NUGET remote: https://api.nuget.org/v3/index.json - BenchmarkDotNet (0.14) - BenchmarkDotNet.Annotations (>= 0.14) + BenchmarkDotNet (0.15) + BenchmarkDotNet.Annotations (>= 0.15) CommandLineParser (>= 2.9.1) Gee.External.Capstone (>= 2.3) Iced (>= 1.17) - Microsoft.CodeAnalysis.CSharp (>= 4.1) - Microsoft.Diagnostics.Runtime (>= 2.2.332302) + Microsoft.CodeAnalysis.CSharp (>= 4.12) + Microsoft.Diagnostics.Runtime (>= 3.1.512801) Microsoft.Diagnostics.Tracing.TraceEvent (>= 3.1.8) Microsoft.DotNet.PlatformAbstractions (>= 3.1.6) - Perfolizer (0.3.17) - System.Management (>= 5.0) - BenchmarkDotNet.Annotations (0.14) + Perfolizer (0.5.2) + System.Management (>= 6.0) + BenchmarkDotNet.Annotations (0.15) CommandLineParser (2.9.1) - FsCheck (2.16.6) - FSharp.Core (>= 4.2.3) - FsCheck.Xunit (2.16.6) - FsCheck (2.16.6) - xunit.extensibility.execution (>= 2.2 < 3.0) - FSharp.Core (9.0.100) + FsCheck (3.3) + FSharp.Core (>= 5.0.2) + FsCheck.Xunit (3.3) + FsCheck (3.3) + FSharp.Core (>= 5.0.2) + xunit.extensibility.execution (>= 2.4.1 < 3.0) + FSharp.Core (9.0.300) Gee.External.Capstone (2.3) Iced (1.21) - Microsoft.CodeAnalysis.Analyzers (3.3.4) - Microsoft.CodeAnalysis.Common (4.8) - Microsoft.CodeAnalysis.Analyzers (>= 3.3.4) - System.Collections.Immutable (>= 7.0) - System.Reflection.Metadata (>= 7.0) - System.Runtime.CompilerServices.Unsafe (>= 6.0) - Microsoft.CodeAnalysis.CSharp (4.8) - Microsoft.CodeAnalysis.Common (4.8) - Microsoft.CodeCoverage (17.12) - Microsoft.Diagnostics.NETCore.Client (0.2.510501) - Microsoft.Extensions.Logging (>= 6.0) - Microsoft.Diagnostics.Runtime (3.1.506101) + Microsoft.CodeAnalysis.Analyzers (4.14) + Microsoft.CodeAnalysis.Common (4.14) + Microsoft.CodeAnalysis.Analyzers (>= 3.11) + System.Collections.Immutable (>= 9.0) + System.Reflection.Metadata (>= 9.0) + Microsoft.CodeAnalysis.CSharp (4.14) + Microsoft.CodeAnalysis.Analyzers (>= 3.11) + Microsoft.CodeAnalysis.Common (4.14) + System.Collections.Immutable (>= 9.0) + System.Reflection.Metadata (>= 9.0) + Microsoft.CodeCoverage (17.14.1) + Microsoft.Diagnostics.NETCore.Client (0.2.621003) + Microsoft.Extensions.Logging.Abstractions (>= 6.0.4) + Microsoft.Diagnostics.Runtime (3.1.512801) Microsoft.Diagnostics.NETCore.Client (>= 0.2.410101) - System.Collections.Immutable (>= 6.0) + Microsoft.Diagnostics.Tracing.TraceEvent (3.1.22) + Microsoft.Diagnostics.NETCore.Client (>= 0.2.510501) + Microsoft.Win32.Registry (>= 5.0) + System.Collections.Immutable (>= 8.0) + System.Reflection.Metadata (>= 8.0) + System.Reflection.TypeExtensions (>= 4.7) System.Runtime.CompilerServices.Unsafe (>= 6.0) - Microsoft.Diagnostics.Tracing.TraceEvent (3.1.8) - Microsoft.Win32.Registry (>= 4.4) - System.Runtime.CompilerServices.Unsafe (>= 5.0) + System.Text.Json (>= 8.0.5) Microsoft.DotNet.PlatformAbstractions (3.1.6) - Microsoft.Extensions.DependencyInjection (8.0) - Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0) - Microsoft.Extensions.DependencyInjection.Abstractions (8.0) - Microsoft.Extensions.Logging (8.0) - Microsoft.Extensions.DependencyInjection (>= 8.0) - Microsoft.Extensions.Logging.Abstractions (>= 8.0) - Microsoft.Extensions.Options (>= 8.0) - Microsoft.Extensions.Logging.Abstractions (8.0) - Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0) - Microsoft.Extensions.Options (8.0.1) - Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0) - Microsoft.Extensions.Primitives (>= 8.0) - Microsoft.Extensions.Primitives (8.0) - Microsoft.NET.Test.Sdk (17.12) - Microsoft.CodeCoverage (>= 17.12) - Microsoft.TestPlatform.TestHost (>= 17.12) - Microsoft.TestPlatform.ObjectModel (17.12) - System.Reflection.Metadata (>= 1.6) - Microsoft.TestPlatform.TestHost (17.12) - Microsoft.TestPlatform.ObjectModel (>= 17.12) - Newtonsoft.Json (>= 13.0.1) + Microsoft.Extensions.DependencyInjection.Abstractions (9.0.5) + Microsoft.Extensions.Logging.Abstractions (9.0.5) + Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.5) + Microsoft.NET.Test.Sdk (17.14.1) + Microsoft.CodeCoverage (>= 17.14.1) + Microsoft.TestPlatform.TestHost (>= 17.14.1) + Microsoft.TestPlatform.ObjectModel (17.14.1) + System.Reflection.Metadata (>= 8.0) + Microsoft.TestPlatform.TestHost (17.14.1) + Microsoft.TestPlatform.ObjectModel (>= 17.14.1) + Newtonsoft.Json (>= 13.0.3) Microsoft.Win32.Registry (5.0) System.Security.AccessControl (>= 5.0) System.Security.Principal.Windows (>= 5.0) Newtonsoft.Json (13.0.3) - Perfolizer (0.3.17) - System.CodeDom (8.0) - System.Collections.Immutable (8.0) - System.Management (8.0) - System.CodeDom (>= 8.0) - System.Reflection.Metadata (8.0) - System.Collections.Immutable (>= 8.0) - System.Runtime.CompilerServices.Unsafe (6.0) - System.Security.AccessControl (6.0) + Perfolizer (0.5.2) + System.CodeDom (9.0.5) + System.Collections.Immutable (9.0.5) + System.IO.Pipelines (10.0.0-preview.5.25277.114) + System.Management (9.0.5) + System.CodeDom (>= 9.0.5) + System.Reflection.Metadata (9.0.5) + System.Reflection.TypeExtensions (4.7) + System.Runtime.CompilerServices.Unsafe (6.1.2) + System.Security.AccessControl (6.0.1) System.Security.Principal.Windows (5.0) - System.Text.Json (9.0) - xunit (2.9.2) - xunit.analyzers (>= 1.16) - xunit.assert (>= 2.9.2) - xunit.core (2.9.2) + System.Text.Encodings.Web (10.0.0-preview.5.25277.114) + System.Text.Json (10.0.0-preview.5.25277.114) + System.IO.Pipelines (>= 10.0.0-preview.5.25277.114) + System.Text.Encodings.Web (>= 10.0.0-preview.5.25277.114) + xunit (2.9.3) + xunit.analyzers (>= 1.18) + xunit.assert (>= 2.9.3) + xunit.core (2.9.3) xunit.abstractions (2.0.3) - xunit.analyzers (1.18) - xunit.assert (2.9.2) - xunit.core (2.9.2) - xunit.extensibility.core (2.9.2) - xunit.extensibility.execution (2.9.2) - xunit.extensibility.core (2.9.2) + xunit.analyzers (1.22) + xunit.assert (2.9.3) + xunit.core (2.9.3) + xunit.extensibility.core (2.9.3) + xunit.extensibility.execution (2.9.3) + xunit.extensibility.core (2.9.3) xunit.abstractions (>= 2.0.3) - xunit.extensibility.execution (2.9.2) - xunit.extensibility.core (2.9.2) - xunit.runner.visualstudio (3.0) + xunit.extensibility.execution (2.9.3) + xunit.extensibility.core (2.9.3) + xunit.runner.visualstudio (3.1.1) GROUP trimtest STORAGE: NONE RESTRICTION: == net9.0 NUGET remote: https://api.nuget.org/v3/index.json - FsCheck (2.16.6) - FSharp.Core (>= 4.2.3) - FsCheck.Xunit (2.16.6) - FsCheck (2.16.6) - xunit.extensibility.execution (>= 2.2 < 3.0) - FSharp.Core (9.0.100) - Microsoft.CodeCoverage (17.12) - Microsoft.NET.Test.Sdk (17.12) - Microsoft.CodeCoverage (>= 17.12) - Microsoft.TestPlatform.TestHost (>= 17.12) - Microsoft.TestPlatform.ObjectModel (17.12) - System.Reflection.Metadata (>= 1.6) - Microsoft.TestPlatform.TestHost (17.12) - Microsoft.TestPlatform.ObjectModel (>= 17.12) - Newtonsoft.Json (>= 13.0.1) + FsCheck (3.3) + FSharp.Core (>= 5.0.2) + FsCheck.Xunit (3.3) + FsCheck (3.3) + FSharp.Core (>= 5.0.2) + xunit.extensibility.execution (>= 2.4.1 < 3.0) + FSharp.Core (9.0.300) + Microsoft.CodeCoverage (17.14.1) + Microsoft.NET.Test.Sdk (17.14.1) + Microsoft.CodeCoverage (>= 17.14.1) + Microsoft.TestPlatform.TestHost (>= 17.14.1) + Microsoft.TestPlatform.ObjectModel (17.14.1) + System.Reflection.Metadata (>= 8.0) + Microsoft.TestPlatform.TestHost (17.14.1) + Microsoft.TestPlatform.ObjectModel (>= 17.14.1) + Newtonsoft.Json (>= 13.0.3) Newtonsoft.Json (13.0.3) - System.Reflection.Metadata (9.0) - System.Text.Json (9.0) - xunit (2.9.2) - xunit.analyzers (>= 1.16) - xunit.assert (>= 2.9.2) - xunit.core (2.9.2) + System.Reflection.Metadata (9.0.5) + System.Text.Json (9.0.5) + xunit (2.9.3) + xunit.analyzers (>= 1.18) + xunit.assert (>= 2.9.3) + xunit.core (2.9.3) xunit.abstractions (2.0.3) - xunit.analyzers (1.18) - xunit.assert (2.9.2) - xunit.console (2.9.2) - xunit.runner.reporters (2.9.2) - xunit.core (2.9.2) - xunit.extensibility.core (2.9.2) - xunit.extensibility.execution (2.9.2) - xunit.extensibility.core (2.9.2) + xunit.analyzers (1.22) + xunit.assert (2.9.3) + xunit.console (2.9.3) + xunit.runner.reporters (2.9.3) + xunit.core (2.9.3) + xunit.extensibility.core (2.9.3) + xunit.extensibility.execution (2.9.3) + xunit.extensibility.core (2.9.3) xunit.abstractions (>= 2.0.3) - xunit.extensibility.execution (2.9.2) - xunit.extensibility.core (2.9.2) - xunit.runner.reporters (2.9.2) - xunit.runner.utility (2.9.2) - xunit.runner.utility (2.9.2) + xunit.extensibility.execution (2.9.3) + xunit.extensibility.core (2.9.3) + xunit.runner.reporters (2.9.3) + xunit.runner.utility (2.9.3) + xunit.runner.utility (2.9.3) xunit.abstractions (>= 2.0.3) diff --git a/src/FSharp.SystemTextJson/Collection.fs b/src/FSharp.SystemTextJson/Collection.fs index 037aac9..7dec44b 100644 --- a/src/FSharp.SystemTextJson/Collection.fs +++ b/src/FSharp.SystemTextJson/Collection.fs @@ -3,6 +3,7 @@ namespace System.Text.Json.Serialization open System open System.Text.Json open System.Text.Json.Serialization.Helpers +open Microsoft.FSharp.Core.CompilerServices type JsonListConverter<'T> internal (fsOptions) = inherit JsonConverter>() @@ -12,12 +13,19 @@ type JsonListConverter<'T> internal (fsOptions) = override _.Read(reader, typeToConvert, options) = expectAlreadyRead JsonTokenType.StartArray "JSON array" &reader typeToConvert - let array = JsonSerializer.Deserialize(&reader, typeof<'T[]>, options) :?> 'T[] + + let mutable l = ListCollector<'T>() + while reader.Read() && reader.TokenType <> JsonTokenType.EndArray do + let value = JsonSerializer.Deserialize(&reader, typeof<'T>, options) + l.Add(value :?> 'T) + let list = l.Close() + if needsNullChecking then - for elem in array do + for elem in list do if isNull (box elem) then failf "Unexpected null inside array. Expected only elements of type %s" tType.Name - array |> List.ofArray + + list override _.Write(writer, value, options) = JsonSerializer.Serialize>(writer, value, options) From af361bb7023e3c069015b3706d5bb17463bb1968 Mon Sep 17 00:00:00 2001 From: Loic Denuziere Date: Mon, 9 Jun 2025 11:17:46 +0200 Subject: [PATCH 2/2] feat: update System.Text.Json 8.0.5 and use JsonTypeInfo for lists --- paket.dependencies | 4 ++-- paket.lock | 15 +++++--------- src/FSharp.SystemTextJson/All.fs | 2 +- src/FSharp.SystemTextJson/Collection.fs | 26 +++++++++++++++---------- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/paket.dependencies b/paket.dependencies index 0cb2b72..75af05c 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -5,7 +5,7 @@ source https://api.nuget.org/v3/index.json nuget FSharp.Core >= 6.0 lowest_matching:true nuget Microsoft.SourceLink.GitHub prerelease copy_local:true nuget Nerdbank.GitVersioning copy_local:true -nuget System.Text.Json >= 6.0.10 lowest_matching: true +nuget System.Text.Json >= 8.0.5 lowest_matching: true group test framework net9.0 @@ -15,7 +15,7 @@ source https://api.nuget.org/v3/index.json nuget FSharp.Core >= 6.0 nuget FsCheck.XUnit nuget Microsoft.NET.Test.Sdk -nuget System.Text.Json >= 8.0.5 prerelease +nuget System.Text.Json >= 8.0.5 nuget xunit nuget xunit.runner.visualstudio nuget BenchmarkDotNet diff --git a/paket.lock b/paket.lock index 6778b5e..fc96b0a 100644 --- a/paket.lock +++ b/paket.lock @@ -22,13 +22,12 @@ NUGET System.Buffers (>= 4.5.1) System.Memory (>= 4.5.5) System.Runtime.CompilerServices.Unsafe (>= 6.0) - System.Text.Json (6.0.10) - Microsoft.Bcl.AsyncInterfaces (>= 6.0) + System.Text.Json (8.0.5) + Microsoft.Bcl.AsyncInterfaces (>= 8.0) System.Buffers (>= 4.5.1) - System.Memory (>= 4.5.4) - System.Numerics.Vectors (>= 4.5) + System.Memory (>= 4.5.5) System.Runtime.CompilerServices.Unsafe (>= 6.0) - System.Text.Encodings.Web (>= 6.0) + System.Text.Encodings.Web (>= 8.0) System.Threading.Tasks.Extensions (>= 4.5.4) System.Threading.Tasks.Extensions (4.6.3) System.Runtime.CompilerServices.Unsafe (>= 6.1.2) @@ -242,7 +241,6 @@ NUGET Perfolizer (0.5.2) System.CodeDom (9.0.5) System.Collections.Immutable (9.0.5) - System.IO.Pipelines (10.0.0-preview.5.25277.114) System.Management (9.0.5) System.CodeDom (>= 9.0.5) System.Reflection.Metadata (9.0.5) @@ -250,10 +248,7 @@ NUGET System.Runtime.CompilerServices.Unsafe (6.1.2) System.Security.AccessControl (6.0.1) System.Security.Principal.Windows (5.0) - System.Text.Encodings.Web (10.0.0-preview.5.25277.114) - System.Text.Json (10.0.0-preview.5.25277.114) - System.IO.Pipelines (>= 10.0.0-preview.5.25277.114) - System.Text.Encodings.Web (>= 10.0.0-preview.5.25277.114) + System.Text.Json (9.0.5) xunit (2.9.3) xunit.analyzers (>= 1.18) xunit.assert (>= 2.9.3) diff --git a/src/FSharp.SystemTextJson/All.fs b/src/FSharp.SystemTextJson/All.fs index dda4656..d9e29d6 100644 --- a/src/FSharp.SystemTextJson/All.fs +++ b/src/FSharp.SystemTextJson/All.fs @@ -41,7 +41,7 @@ type JsonFSharpConverter(fsOptions: JsonFSharpOptions, [] overrides: I static member internal CreateConverter(typeToConvert, options, fsOptions) = match TypeCache.getKind typeToConvert with - | TypeCache.TypeKind.List -> JsonListConverter.CreateConverter(typeToConvert, fsOptions) + | TypeCache.TypeKind.List -> JsonListConverter.CreateConverter(typeToConvert, options, fsOptions) | TypeCache.TypeKind.Set -> JsonSetConverter.CreateConverter(typeToConvert, fsOptions) | TypeCache.TypeKind.Map -> JsonMapConverter.CreateConverter(typeToConvert, options, fsOptions) | TypeCache.TypeKind.Tuple -> JsonTupleConverter.CreateConverter(typeToConvert, fsOptions) diff --git a/src/FSharp.SystemTextJson/Collection.fs b/src/FSharp.SystemTextJson/Collection.fs index 7dec44b..b5accb7 100644 --- a/src/FSharp.SystemTextJson/Collection.fs +++ b/src/FSharp.SystemTextJson/Collection.fs @@ -3,21 +3,22 @@ namespace System.Text.Json.Serialization open System open System.Text.Json open System.Text.Json.Serialization.Helpers +open System.Text.Json.Serialization.Metadata open Microsoft.FSharp.Core.CompilerServices -type JsonListConverter<'T> internal (fsOptions) = +type JsonListConverter<'T> internal (options, fsOptions) = inherit JsonConverter>() let tType = typeof<'T> let tIsNullable = isNullableFieldType fsOptions tType let needsNullChecking = not tIsNullable && not tType.IsValueType + let typeInfo = JsonTypeInfo.CreateJsonTypeInfo<'T>(options) - override _.Read(reader, typeToConvert, options) = + override _.Read(reader, typeToConvert, _options) = expectAlreadyRead JsonTokenType.StartArray "JSON array" &reader typeToConvert let mutable l = ListCollector<'T>() while reader.Read() && reader.TokenType <> JsonTokenType.EndArray do - let value = JsonSerializer.Deserialize(&reader, typeof<'T>, options) - l.Add(value :?> 'T) + l.Add(JsonSerializer.Deserialize<'T>(&reader, typeInfo)) let list = l.Close() if needsNullChecking then @@ -32,7 +33,7 @@ type JsonListConverter<'T> internal (fsOptions) = override _.HandleNull = true - new(fsOptions: JsonFSharpOptions) = JsonListConverter<'T>(fsOptions.Record) + new(options, fsOptions: JsonFSharpOptions) = JsonListConverter<'T>(options, fsOptions.Record) type JsonListConverter(fsOptions) = inherit JsonConverterFactory() @@ -40,18 +41,23 @@ type JsonListConverter(fsOptions) = static member internal CanConvert(typeToConvert: Type) = TypeCache.isList typeToConvert - static member internal CreateConverter(typeToConvert: Type, fsOptions: JsonFSharpOptions) = + static member internal CreateConverter + (typeToConvert: Type, options: JsonSerializerOptions, fsOptions: JsonFSharpOptions) + = typedefof> .MakeGenericType([| typeToConvert.GetGenericArguments().[0] |]) - .GetConstructor([| typeof |]) - .Invoke([| fsOptions |]) + .GetConstructor( + [| typeof + typeof |] + ) + .Invoke([| options; fsOptions |]) :?> JsonConverter override _.CanConvert(typeToConvert) = JsonListConverter.CanConvert(typeToConvert) - override _.CreateConverter(typeToConvert, _options) = - JsonListConverter.CreateConverter(typeToConvert, fsOptions) + override _.CreateConverter(typeToConvert, options) = + JsonListConverter.CreateConverter(typeToConvert, options, fsOptions) type JsonSetConverter<'T when 'T: comparison> internal (fsOptions) = inherit JsonConverter>()