Skip to content

Commit

Permalink
Add Serdes stream methods (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
deviousasti authored Sep 2, 2022
1 parent 0fc3cda commit 700f055
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ The `Unreleased` section name is replaced by the expected version of next releas
## [Unreleased]

### Added
- Add `SerializeToStream` and `DeserializeFromStream` methods to Serdes [#83](https://github.com/jet/FsCodec/pull/83)

### Changed
### Removed
### Fixed
Expand Down
30 changes: 26 additions & 4 deletions src/FsCodec.NewtonsoftJson/Serdes.fs
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
namespace FsCodec.NewtonsoftJson

open Newtonsoft.Json
open System.IO
open System.Text

/// Serializes to/from strings using the supplied JsonSerializerSettings
type Serdes(options : JsonSerializerSettings) =
// Why are we creating a serializer here instead of using JsonConvert.Serialize?
// Because, under the hood, JsonConvert creates a serializer instance for *each* call
// Source:
// https://github.com/JamesNK/Newtonsoft.Json/blob/4dc9af66e07dea321ad101bfb379326127251a80/Src/Newtonsoft.Json/JsonConvert.cs#L817
// It's consistent with the stream implementation
let serializer = JsonSerializer.Create(options)

/// <summary>The <c>JsonSerializerSettings</c> used by this instance.</summary>
member _.Options : JsonSerializerSettings = options

/// Serializes given value to a JSON string.
member _.Serialize<'T>(value : 'T) =
JsonConvert.SerializeObject(value, options)
member _.Serialize<'T>(value : 'T) : string =
use sw = new StringWriter()
use writer = new JsonTextWriter(sw)
serializer.Serialize(writer, value)
sw.ToString()

/// Deserializes value of given type from JSON string.
member x.Deserialize<'T>(json : string) : 'T =
JsonConvert.DeserializeObject<'T>(json, options)
member _.Deserialize<'T>(json : string) : 'T =
use reader = new JsonTextReader(new StringReader(json))
serializer.Deserialize<'T>(reader)

/// Serializes and writes given value to a stream.
member _.SerializeToStream<'T>(value : 'T, utf8Stream : Stream) =
use writer = new JsonTextWriter(new StreamWriter(utf8Stream, Encoding.UTF8), CloseOutput = false)
serializer.Serialize(writer, value)

/// Deserializes by reading from a stream.
member x.DeserializeFromStream<'T>(utf8Stream : Stream) =
use reader = new JsonTextReader(new StreamReader(utf8Stream, Encoding.UTF8))
serializer.Deserialize<'T>(reader)
14 changes: 12 additions & 2 deletions src/FsCodec.SystemTextJson/Serdes.fs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
namespace FsCodec.SystemTextJson

open System.IO
open System.Text.Json

/// Serializes to/from strings using the supplied Options
type Serdes(options : JsonSerializerOptions) =

/// <summary>The <c>JsonSerializerOptions</c> used by this instance.</summary>
member _.Options : JsonSerializerOptions = options

Expand All @@ -13,5 +14,14 @@ type Serdes(options : JsonSerializerOptions) =
JsonSerializer.Serialize<'T>(value, options)

/// Deserializes value of given type from JSON string.
member x.Deserialize<'T>(json : string) : 'T =
member _.Deserialize<'T>(json : string) : 'T =
JsonSerializer.Deserialize<'T>(json, options)

/// Serializes and writes given value to a stream.
member _.SerializeToStream<'T>(value : 'T, utf8Stream : Stream) =
JsonSerializer.Serialize<'T>(utf8Stream, value, options)

/// Deserializes by reading from a stream.
member _.DeserializeFromStream<'T>(utf8Stream : Stream) =
JsonSerializer.Deserialize<'T>(utf8Stream, options)

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<Compile Include="UnionConverterTests.fs" />
<Compile Include="VerbatimUtf8ConverterTests.fs" />
<Compile Include="SomeNullHandlingTests.fs" />
<Compile Include="StreamTests.fs" />
</ItemGroup>

<ItemGroup>
Expand Down
23 changes: 23 additions & 0 deletions tests/FsCodec.NewtonsoftJson.Tests/StreamTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#if SYSTEM_TEXT_JSON
module FsCodec.SytemTextJson.Tests.StreamTests
open FsCodec.SystemTextJson
#else
module FsCodec.NewtonsoftJson.Tests.StreamTests
open FsCodec.NewtonsoftJson
#endif

open Xunit
open System.IO
open Swensen.Unquote

let serdes = Serdes Options.Default

type Rec = { a : int; b : string; c : string }

let [<Fact>] ``Can serialize/deserialize to stream`` () =
let value = { a = 10; b = "10"; c = null }
use stream = new MemoryStream()
serdes.SerializeToStream(value, stream)
stream.Seek(0L, SeekOrigin.Begin) |> ignore
let value' = serdes.DeserializeFromStream(stream)
<@ value = value' @>
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<Compile Include="SerdesTests.fs" />
<Compile Include="UmxInteropTests.fs" />
<Compile Include="TypeSafeEnumConverterTests.fs" />
<Compile Include="..\FsCodec.NewtonsoftJson.Tests\StreamTests.fs" Link="StreamTests.fs" />
<Compile Include="..\FsCodec.NewtonsoftJson.Tests\Fixtures.fs">
<Link>Fixtures.fs</Link>
</Compile>
Expand Down

0 comments on commit 700f055

Please sign in to comment.