Skip to content

Commit

Permalink
Format
Browse files Browse the repository at this point in the history
  • Loading branch information
bartelink committed Jan 24, 2024
1 parent 8ab6f58 commit 0340ae8
Show file tree
Hide file tree
Showing 22 changed files with 129 additions and 141 deletions.
2 changes: 2 additions & 0 deletions FsCodec.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=Pickler/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=roundtrips/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=serdes/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
8 changes: 4 additions & 4 deletions src/FsCodec.Box/ByteArray.fs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
namespace FsCodec

open System.Runtime.CompilerServices
open System
open System.Runtime.CompilerServices

[<Extension; AbstractClass; Sealed>]
type ByteArray private () =

static member BytesToReadOnlyMemory(x : byte[]) : ReadOnlyMemory<byte> =
static member BytesToReadOnlyMemory(x: byte[]): ReadOnlyMemory<byte> =
if x = null then ReadOnlyMemory.Empty
else ReadOnlyMemory x

static member ReadOnlyMemoryToBytes(x : ReadOnlyMemory<byte>) : byte[] =
static member ReadOnlyMemoryToBytes(x: ReadOnlyMemory<byte>): byte[] =
if x.IsEmpty then null
else x.ToArray()

/// <summary>Adapt an IEventCodec that handles ReadOnlyMemory&lt;byte&gt; Event Bodies to instead use <c>byte[]</c>
/// Ideally not used as it makes pooling problematic; only provided for interop/porting scaffolding wrt Equinox V3 and EventStore.Client etc</summary>
[<Extension>]
static member ToByteArrayCodec<'Event, 'Context>(native : IEventCodec<'Event, ReadOnlyMemory<byte>, 'Context>)
static member ToByteArrayCodec<'Event, 'Context>(native: IEventCodec<'Event, ReadOnlyMemory<byte>, 'Context>)
: IEventCodec<'Event, byte[], 'Context> =
FsCodec.Core.EventCodec.Map(native, Func<_, _> ByteArray.ReadOnlyMemoryToBytes, Func<_, _> ByteArray.BytesToReadOnlyMemory)
2 changes: 1 addition & 1 deletion src/FsCodec.Box/Codec.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ open System.Runtime.InteropServices
[<AbstractClass; Sealed>]
type Codec private () =

static let defEncoder : TypeShape.UnionContract.IEncoder<obj> = TypeShape.UnionContract.BoxEncoder() :> _
static let defEncoder: TypeShape.UnionContract.IEncoder<obj> = TypeShape.UnionContract.BoxEncoder() :> _

/// <summary>Generate an <c>IEventCodec</c> that handles <c>obj</c> (boxed .NET <c>Object</c>) Event Bodies.<br/>
/// Uses <c>up</c>, <c>down</c> functions to handle upconversion/downconversion and eventId/correlationId/causationId mapping
Expand Down
2 changes: 1 addition & 1 deletion src/FsCodec.Box/Compression.fs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ type [<Struct>] CompressionOptions = { minSize: int; minGain: int } with
static member Uncompressed = { minSize = Int32.MaxValue; minGain = 0 }

[<Extension; AbstractClass; Sealed>]
type Compression =
type Compression private ()=

static member Utf8ToEncodedDirect(x: ReadOnlyMemory<byte>): EncodedBody =
EncodedMaybeCompressed.encodeUncompressed x
Expand Down
10 changes: 5 additions & 5 deletions src/FsCodec.Box/CoreCodec.fs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type Codec private () =
{ new FsCodec.IEventCodec<'Event, 'Body, 'Context> with

member _.Encode(context, event) =
let struct (c, meta : 'Meta voption, eventId, correlationId, causationId, timestamp) = down.Invoke(context, event)
let struct (c, meta: 'Meta voption, eventId, correlationId, causationId, timestamp) = down.Invoke(context, event)
let enc = dataCodec.Encode c
let meta' = match meta with ValueSome x -> encoder.Encode<'Meta> x | ValueNone -> Unchecked.defaultof<'Body>
EventData(enc.CaseName, enc.Payload, meta', eventId, correlationId, causationId, timestamp)
Expand Down Expand Up @@ -95,18 +95,18 @@ type Codec private () =
[<Optional; DefaultParameterValue(null)>] ?rejectNullaryCases)
: FsCodec.IEventCodec<'Event, 'Body, unit> =

let mapCausation () (m : 'Meta voption) = struct (m, Guid.NewGuid(), null, null)
let mapCausation () (m: 'Meta voption) = struct (m, Guid.NewGuid(), null, null)
Codec.Create(encoder, up = up, down = down, mapCausation = mapCausation, ?rejectNullaryCases = rejectNullaryCases)

/// <summary>Generate an <code>IEventCodec</code> using the supplied <c>encoder</c>.<br/>
/// The Event Type Names are inferred based on either explicit <c>DataMember(Name=</c> Attributes, or (if unspecified) the Discriminated Union Case Name
/// <c>'Union</c> must be tagged with <c>interface TypeShape.UnionContract.IUnionContract</c> to signify this scheme applies.</summary>
static member Create<'Body, 'Union when 'Union :> TypeShape.UnionContract.IUnionContract>
( encoder : TypeShape.UnionContract.IEncoder<'Body>,
( encoder: TypeShape.UnionContract.IEncoder<'Body>,
// <summary>Enables one to fail encoder generation if union contains nullary cases. Defaults to <c>false</c>, i.e. permitting them.</summary>
[<Optional; DefaultParameterValue(null)>] ?rejectNullaryCases)
: FsCodec.IEventCodec<'Union, 'Body, unit> =

let up (_e : FsCodec.ITimelineEvent<'Body>) (u : 'Union) : 'Union = u
let down (event : 'Union) = struct (event, ValueNone (*Meta*), ValueNone (*Timestamp*))
let up (_e: FsCodec.ITimelineEvent<'Body>) (u: 'Union): 'Union = u
let down (event: 'Union) = struct (event, ValueNone (*Meta*), ValueNone (*Timestamp*))
Codec.Create(encoder, up = up, down = down, ?rejectNullaryCases = rejectNullaryCases)
4 changes: 2 additions & 2 deletions src/FsCodec.NewtonsoftJson/Codec.fs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
namespace FsCodec.NewtonsoftJson.Core

/// Newtonsoft.Json implementation of TypeShape.UnionContractEncoder's IEncoder that encodes direct to a UTF-8 ReadOnlyMemory<byte>
type ReadOnlyMemoryEncoder(serdes : FsCodec.NewtonsoftJson.Serdes) =
type ReadOnlyMemoryEncoder(serdes: FsCodec.NewtonsoftJson.Serdes) =
interface TypeShape.UnionContract.IEncoder<System.ReadOnlyMemory<byte>> with
member _.Empty = System.ReadOnlyMemory.Empty
member _.Encode(value: 'T) = serdes.SerializeToUtf8(value) |> System.ReadOnlyMemory
member _.Decode(utf8json: System.ReadOnlyMemory<byte>) : 'T = serdes.Deserialize<'T>(utf8json)
member _.Decode(utf8json: System.ReadOnlyMemory<byte>): 'T = serdes.Deserialize<'T>(utf8json)

namespace FsCodec.NewtonsoftJson

Expand Down
22 changes: 11 additions & 11 deletions src/FsCodec.NewtonsoftJson/Options.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ open System.Runtime.InteropServices
type Options private () =

/// <summary>Analogous to <c>System.Text.Json</c>'s <c>JsonSerializerOptions.Default</c> - allows for sharing/caching of the default profile as defined by <c>Options.Create()</c></summary>
static member val Default : JsonSerializerSettings = Options.Create()
static member val Default: JsonSerializerSettings = Options.Create()

/// Creates a default set of serializer settings used by Json serialization. When used with no args, same as JsonSerializerSettings.CreateDefault()
/// With one difference - it inhibits the JSON.NET out of the box parsing of strings that look like dates (see https://github.com/JamesNK/Newtonsoft.Json/issues/862)
static member CreateDefault
( [<Optional; ParamArray>] converters : JsonConverter[],
( [<Optional; ParamArray>] converters: JsonConverter[],
// Use multi-line, indented formatting when serializing JSON; defaults to false.
[<Optional; DefaultParameterValue(null)>] ?indent : bool,
[<Optional; DefaultParameterValue(null)>] ?indent: bool,
// Render idiomatic camelCase for PascalCase items by using `CamelCasePropertyNamesContractResolver`. Defaults to false.
[<Optional; DefaultParameterValue(null)>] ?camelCase : bool,
[<Optional; DefaultParameterValue(null)>] ?camelCase: bool,
// Ignore null values in input data; defaults to false.
[<Optional; DefaultParameterValue(null)>] ?ignoreNulls : bool,
[<Optional; DefaultParameterValue(null)>] ?ignoreNulls: bool,
// Error on missing values (as opposed to letting them just be default-initialized); defaults to false.
[<Optional; DefaultParameterValue(null)>] ?errorOnMissing : bool) =
[<Optional; DefaultParameterValue(null)>] ?errorOnMissing: bool) =
let indent = defaultArg indent false
let camelCase = defaultArg camelCase false
let ignoreNulls = defaultArg ignoreNulls false
Expand All @@ -42,16 +42,16 @@ type Options private () =
/// - everything else is as per CreateDefault:- i.e. emit nulls instead of omitting fields etc
static member Create
( // List of converters to apply. An implicit OptionConverter() will be prepended and/or be used as a default
[<Optional; ParamArray>] converters : JsonConverter[],
[<Optional; ParamArray>] converters: JsonConverter[],
// Use multi-line, indented formatting when serializing JSON; defaults to false.
[<Optional; DefaultParameterValue(null)>] ?indent : bool,
[<Optional; DefaultParameterValue(null)>] ?indent: bool,
// Render idiomatic camelCase for PascalCase items by using `CamelCasePropertyNamesContractResolver`.
// Defaults to false on basis that you'll use record and tuple field names that are camelCase (and hence not `CLSCompliant`).
[<Optional; DefaultParameterValue(null)>] ?camelCase : bool,
[<Optional; DefaultParameterValue(null)>] ?camelCase: bool,
// Ignore null values in input data; defaults to `false`.
[<Optional; DefaultParameterValue(null)>] ?ignoreNulls : bool,
[<Optional; DefaultParameterValue(null)>] ?ignoreNulls: bool,
// Error on missing values (as opposed to letting them just be default-initialized); defaults to false
[<Optional; DefaultParameterValue(null)>] ?errorOnMissing : bool) =
[<Optional; DefaultParameterValue(null)>] ?errorOnMissing: bool) =
Options.CreateDefault(
converters = [| OptionConverter()
match converters with null -> () | xs -> yield! xs |],
Expand Down
27 changes: 10 additions & 17 deletions src/FsCodec.NewtonsoftJson/Pickler.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,52 +14,45 @@ type JsonPickler<'T>() =
inherit JsonConverter()

static let isMatchingType =
let rec isMatching (ts : Type list) =
match ts with
let rec isMatching = function
| [] -> false
| t :: _ when t = typeof<'T> -> true
| t :: tl ->
let tail =
[ match t.BaseType with null -> () | bt -> yield bt
yield! t.GetInterfaces()
yield! tl ]

isMatching tail

memoize (fun t -> isMatching [t])

abstract Write : writer: JsonWriter * serializer: JsonSerializer * source: 'T -> unit
abstract Read : reader: JsonReader * serializer: JsonSerializer -> 'T
abstract Write: writer: JsonWriter * serializer: JsonSerializer * source: 'T -> unit
abstract Read: reader: JsonReader * serializer: JsonSerializer -> 'T

override _.CanConvert t = isMatchingType t

override _.CanRead = true
override _.CanWrite = true

override x.WriteJson(writer : JsonWriter, value : obj, serializer : JsonSerializer) =
override x.WriteJson(writer: JsonWriter, value: obj, serializer: JsonSerializer) =
x.Write(writer, serializer, value :?> 'T)

override x.ReadJson(reader : JsonReader, _ : Type, _ : obj, serializer : JsonSerializer) =
override x.ReadJson(reader: JsonReader, _objectType: Type, _existingValue: obj, serializer: JsonSerializer) =
x.Read(reader, serializer) :> obj

/// Json Converter that serializes based on an isomorphic type
[<AbstractClass>]
type JsonIsomorphism<'T, 'U>(?targetPickler : JsonPickler<'U>) =
type JsonIsomorphism<'T, 'U>(?targetPickler: JsonPickler<'U>) =
inherit JsonPickler<'T>()

abstract Pickle : 'T -> 'U
abstract UnPickle : 'U -> 'T
abstract Pickle: 'T -> 'U
abstract UnPickle: 'U -> 'T

override x.Write(writer : JsonWriter, serializer : JsonSerializer, source : 'T) =
override x.Write(writer: JsonWriter, serializer: JsonSerializer, source: 'T) =
let target = x.Pickle source
match targetPickler with
| None -> serializer.Serialize(writer, target, typeof<'U>)
| Some p -> p.Write(writer, serializer, target)

override x.Read(reader : JsonReader, serializer : JsonSerializer) =
override x.Read(reader: JsonReader, serializer: JsonSerializer) =
let target =
match targetPickler with
| None -> serializer.Deserialize<'U>(reader)
| Some p -> p.Read(reader, serializer)

x.UnPickle target
40 changes: 20 additions & 20 deletions src/FsCodec.NewtonsoftJson/Serdes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ module private CharBuffersPool =
module private Utf8BytesEncoder =
let private streamManager = Microsoft.IO.RecyclableMemoryStreamManager()
let rentStream () = streamManager.GetStream("bytesEncoder")
let wrapAsStream (utf8json : ReadOnlyMemory<byte>) =
let wrapAsStream (utf8json: ReadOnlyMemory<byte>) =
// This is the most efficient way of approaching this without using Spans etc.
// RecyclableMemoryStreamManager does not have any wins to provide us
new MemoryStream(utf8json.ToArray(), writable = false)
let makeJsonReader(ms : MemoryStream) =
let makeJsonReader(ms: MemoryStream) =
new JsonTextReader(new StreamReader(ms), ArrayPool = CharBuffersPool.instance)
let private utf8NoBom = System.Text.UTF8Encoding(false, true)
let makeJsonWriter ms =
Expand All @@ -30,59 +30,59 @@ module private Utf8BytesEncoder =
new JsonTextWriter(sw, ArrayPool = CharBuffersPool.instance)

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

// Cache serializer instance to avoid JsonConvert helpers creating one per call; see
// https://github.com/JamesNK/Newtonsoft.Json/blob/4dc9af66e07dea321ad101bfb379326127251a80/Src/Newtonsoft.Json/JsonConvert.cs#L817
let serializer = JsonSerializer.Create(options)

static let def = lazy Serdes Options.Default
/// Cached shortcut for Serdes Options.Default
static member Default : Serdes = def.Value
static member Default: Serdes = def.Value

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

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

/// Serializes given value to a Byte Array, suitable for wrapping as a <c>ReadOnlyMemory</c>.
member _.SerializeToUtf8(value : 'T) : byte[] =
member _.SerializeToUtf8(value: 'T): byte[] =
use ms = Utf8BytesEncoder.rentStream ()
( use jsonWriter = Utf8BytesEncoder.makeJsonWriter ms
serializer.Serialize(jsonWriter, value, typeof<'T>))
// TOCONSIDER as noted in the comments on RecyclableMemoryStream.ToArray, ideally we'd be continuing the rental and passing out a Span
ms.ToArray()

/// Serializes and writes given value to a stream.
member _.SerializeToStream<'T>(value: 'T, utf8Stream: Stream) =
// We're setting CloseOutput = false, because that's the default behavior in STJ
// but also mostly because it's rude to close without asking
use streamWriter = new StreamWriter(utf8Stream, System.Text.Encoding.UTF8, 128, leaveOpen = true)
use writer = new JsonTextWriter(streamWriter, CloseOutput = false)
serializer.Serialize(writer, value)
streamWriter.Flush()

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

/// Deserializes value of given type from a UTF8 JSON Buffer.
member _.Deserialize<'T>(utf8json : ReadOnlyMemory<byte>) : 'T =
member _.Deserialize<'T>(utf8json: ReadOnlyMemory<byte>): 'T =
use ms = Utf8BytesEncoder.wrapAsStream utf8json
use jsonReader = Utf8BytesEncoder.makeJsonReader ms
serializer.Deserialize<'T>(jsonReader)

/// Deserializes value of given type from a JObject
member _.Deserialize<'T>(parsed : Newtonsoft.Json.Linq.JObject) : 'T =
member _.Deserialize<'T>(parsed: Newtonsoft.Json.Linq.JObject): 'T =
parsed.ToObject(typeof<'T>, serializer) :?> 'T

/// Serializes and writes given value to a stream.
member _.SerializeToStream<'T>(value : 'T, utf8Stream : Stream) =
// We're setting CloseOutput = false, because that's the default behavior in STJ
// but also mostly because it's rude to close without asking
use streamWriter = new StreamWriter(utf8Stream, System.Text.Encoding.UTF8, 128, leaveOpen = true)
use writer = new JsonTextWriter(streamWriter, CloseOutput = false)
serializer.Serialize(writer, value)
streamWriter.Flush()

/// Deserializes by reading from a stream.
member _.DeserializeFromStream<'T>(utf8Stream : Stream) =
member _.DeserializeFromStream<'T>(utf8Stream: Stream) =
use reader = new JsonTextReader(new StreamReader(utf8Stream, System.Text.Encoding.UTF8))
serializer.Deserialize<'T>(reader)
2 changes: 1 addition & 1 deletion src/FsCodec.NewtonsoftJson/TypeSafeEnumConverter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type TypeSafeEnumConverter() =
let str = FsCodec.Union.caseNameT t value
writer.WriteValue str

override _.ReadJson(reader : JsonReader, t: Type, _: obj, _: JsonSerializer) =
override _.ReadJson(reader: JsonReader, t: Type, _: obj, _: JsonSerializer) =
if reader.TokenType <> JsonToken.String then
sprintf "Unexpected token when reading TypeSafeEnum: %O" reader.TokenType |> JsonSerializationException |> raise
let str = reader.Value :?> string
Expand Down
2 changes: 1 addition & 1 deletion src/FsCodec.NewtonsoftJson/UnionConverter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module private UnionInfo =

/// Prepare arguments for the Case class ctor based on the kind of case and how F# maps that to a Type
/// and/or whether we need to let json.net step in to convert argument types
let mapTargetCaseArgs (inputJObject : JObject) serializer : PropertyInfo[] -> obj [] = function
let mapTargetCaseArgs (inputJObject: JObject) serializer: PropertyInfo[] -> obj [] = function
| [| singleCaseArg |] when propTypeRequiresConstruction singleCaseArg.PropertyType ->
[| inputJObject.ToObject(singleCaseArg.PropertyType, serializer) |]
| multipleFieldsInCustomCaseType ->
Expand Down
7 changes: 3 additions & 4 deletions src/FsCodec.NewtonsoftJson/VerbatimUtf8Converter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ open System
type VerbatimUtf8JsonConverter() =
inherit JsonConverter()

override _.CanConvert(t : Type) =
typeof<byte[]>.Equals(t)
override _.CanConvert t = typeof<byte[]> = t

override _.WriteJson(writer : JsonWriter, value : obj, serializer : JsonSerializer) =
override _.WriteJson(writer: JsonWriter, value: obj, serializer: JsonSerializer) =
let array = value :?> byte[]
if array = null || array.Length = 0 then serializer.Serialize(writer, null)
else writer.WriteRawValue(System.Text.Encoding.UTF8.GetString(array))

override _.ReadJson(reader : JsonReader, _ : Type, _ : obj, _ : JsonSerializer) =
override _.ReadJson(reader: JsonReader, _: Type, _: obj, _: JsonSerializer) =
let token = JToken.Load reader
if token.Type = JTokenType.Null then null
else token |> string |> System.Text.Encoding.UTF8.GetBytes |> box
2 changes: 1 addition & 1 deletion src/FsCodec.SystemTextJson/CodecJsonElement.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ type JsonElementEncoder(serdes: FsCodec.SystemTextJson.Serdes) =
interface TypeShape.UnionContract.IEncoder<System.Text.Json.JsonElement> with
member _.Empty = Unchecked.defaultof<System.Text.Json.JsonElement>
member _.Encode(value: 'T) = serdes.SerializeToElement(value)
member _.Decode<'T>(json: System.Text.Json.JsonElement) : 'T = serdes.Deserialize<'T>(json)
member _.Decode<'T>(json: System.Text.Json.JsonElement): 'T = serdes.Deserialize<'T>(json)

namespace FsCodec.SystemTextJson

Expand Down
Loading

0 comments on commit 0340ae8

Please sign in to comment.