Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions src/Decode.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1264,7 +1264,7 @@ module Decode =
and private autoDecodeRecordsAndUnions extra (caseStrategy : CaseStrategy) (isOptional : bool) (t: System.Type): BoxedDecoder =
// Add the decoder to extra in case one of the fields is recursive
let decoderRef = ref Unchecked.defaultof<_>
let extra = extra |> Map.add t.FullName decoderRef
let extra = extra |> Map.add (getTypeName t) decoderRef
let decoder =
if FSharpType.IsRecord(t, allowAccessToPrivateRepresentation=true) then
let decoders =
Expand Down Expand Up @@ -1301,8 +1301,8 @@ Documentation available at: https://thoth-org.github.io/Thoth.Json/documentation
decoder


and private autoDecoder (extra: Map<string, ref<BoxedDecoder>>) caseStrategy (isOptional : bool) (t: System.Type) : BoxedDecoder =
let fullname = t.FullName
and private autoDecoder (extra: Map<TypeName, ref<BoxedDecoder>>) caseStrategy (isOptional : bool) (t: System.Type) : BoxedDecoder =
let fullname = getTypeName t
match Map.tryFind fullname extra with
| Some decoderRef -> boxDecoder(fun path value -> decoderRef.contents.BoxedDecoder path value)
| None ->
Expand Down Expand Up @@ -1380,29 +1380,29 @@ If you can't use one of these types, please pass an extra decoder.
Documentation available at: https://thoth-org.github.io/Thoth.Json/documentation/auto/extra-coders.html#ready-to-use-extra-coders
""" t.FullName
else
if fullname = typeof<bool>.FullName then
if fullname = getTypeName typeof<bool> then
boxDecoder bool
elif fullname = typedefof<unit>.FullName then
elif fullname = getTypeName typedefof<unit> then
boxDecoder unit
elif fullname = typeof<string>.FullName then
elif fullname = getTypeName typeof<string> then
boxDecoder string
elif fullname = typeof<char>.FullName then
elif fullname = getTypeName typeof<char> then
boxDecoder char
elif fullname = typeof<sbyte>.FullName then
elif fullname = getTypeName typeof<sbyte> then
boxDecoder sbyte
elif fullname = typeof<byte>.FullName then
elif fullname = getTypeName typeof<byte> then
boxDecoder byte
elif fullname = typeof<int16>.FullName then
elif fullname = getTypeName typeof<int16> then
boxDecoder int16
elif fullname = typeof<uint16>.FullName then
elif fullname = getTypeName typeof<uint16> then
boxDecoder uint16
elif fullname = typeof<int>.FullName then
elif fullname = getTypeName typeof<int> then
boxDecoder int
elif fullname = typeof<uint32>.FullName then
elif fullname = getTypeName typeof<uint32> then
boxDecoder uint32
elif fullname = typeof<float>.FullName then
elif fullname = getTypeName typeof<float> then
boxDecoder float
elif fullname = typeof<float32>.FullName then
elif fullname = getTypeName typeof<float32> then
boxDecoder float32
// These number types require extra libraries in Fable. To prevent penalizing
// all users, extra decoders (withInt64, etc) must be passed when they're needed.
Expand All @@ -1415,15 +1415,15 @@ Documentation available at: https://thoth-org.github.io/Thoth.Json/documentation
// boxDecoder bigint
// elif fullname = typeof<decimal>.FullName then
// boxDecoder decimal
elif fullname = typeof<System.DateTime>.FullName then
elif fullname = getTypeName typeof<System.DateTime> then
boxDecoder datetimeUtc
elif fullname = typeof<System.DateTimeOffset>.FullName then
elif fullname = getTypeName typeof<System.DateTimeOffset> then
boxDecoder datetimeOffset
elif fullname = typeof<System.TimeSpan>.FullName then
elif fullname = getTypeName typeof<System.TimeSpan> then
boxDecoder timespan
elif fullname = typeof<System.Guid>.FullName then
elif fullname = getTypeName typeof<System.Guid> then
boxDecoder guid
elif fullname = typeof<obj>.FullName then
elif fullname = getTypeName typeof<obj> then
boxDecoder (fun _ v ->
if Helpers.isNullValue v then Ok(null: obj)
else v.Value<obj>() |> Ok)
Expand Down
46 changes: 23 additions & 23 deletions src/Encode.fs
Original file line number Diff line number Diff line change
Expand Up @@ -369,17 +369,17 @@ module Encode =
(d :?> EncoderCrate<'T>).UnboxedEncoder

let private (|StringifiableType|_|) (t: System.Type): (obj->string) option =
let fullName = t.FullName
if fullName = typeof<string>.FullName then
let fullName = getTypeName t
if fullName = getTypeName typeof<string> then
Some unbox
elif fullName = typeof<System.Guid>.FullName then
elif fullName = getTypeName typeof<System.Guid> then
Some(fun (v: obj) -> (v :?> System.Guid).ToString())
else None

let rec private autoEncodeRecordsAndUnions extra (caseStrategy : CaseStrategy) (skipNullField : bool) (t: System.Type) : BoxedEncoder =
// Add the encoder to extra in case one of the fields is recursive
let encoderRef = ref Unchecked.defaultof<_>
let extra = extra |> Map.add t.FullName encoderRef
let extra = extra |> Map.add (getTypeName t) encoderRef
let encoder =
if FSharpType.IsRecord(t, allowAccessToPrivateRepresentation=true) then
let setters =
Expand Down Expand Up @@ -439,8 +439,8 @@ Documentation available at: https://thoth-org.github.io/Thoth.Json/documentation
ar.Add(encoder.Encode(x))
ar :> JsonValue)

and private autoEncoder (extra: Map<string, ref<BoxedEncoder>>) caseStrategy (skipNullField : bool) (t: System.Type) : BoxedEncoder =
let fullname = t.FullName
and private autoEncoder (extra: Map<TypeName, ref<BoxedEncoder>>) caseStrategy (skipNullField : bool) (t: System.Type) : BoxedEncoder =
let fullname = getTypeName t
match Map.tryFind fullname extra with
| Some encoderRef -> boxEncoder(fun v -> encoderRef.contents.BoxedEncoder v)
| None ->
Expand Down Expand Up @@ -521,29 +521,29 @@ Thoth.Json.Net only support the folluwing enum types:
If you can't use one of these types, please pass an extra encoder.
""" t.FullName
else
if fullname = typeof<bool>.FullName then
if fullname = getTypeName typeof<bool> then
boxEncoder bool
elif fullname = typeof<unit>.FullName then
elif fullname = getTypeName typeof<unit> then
boxEncoder unit
elif fullname = typeof<string>.FullName then
elif fullname = getTypeName typeof<string> then
boxEncoder string
elif fullname = typeof<char>.FullName then
elif fullname = getTypeName typeof<char> then
boxEncoder char
elif fullname = typeof<sbyte>.FullName then
elif fullname = getTypeName typeof<sbyte> then
boxEncoder sbyte
elif fullname = typeof<byte>.FullName then
elif fullname = getTypeName typeof<byte> then
boxEncoder byte
elif fullname = typeof<int16>.FullName then
elif fullname = getTypeName typeof<int16> then
boxEncoder int16
elif fullname = typeof<uint16>.FullName then
elif fullname = getTypeName typeof<uint16> then
boxEncoder uint16
elif fullname = typeof<int>.FullName then
elif fullname = getTypeName typeof<int> then
boxEncoder int
elif fullname = typeof<uint32>.FullName then
elif fullname = getTypeName typeof<uint32> then
boxEncoder uint32
elif fullname = typeof<float>.FullName then
elif fullname = getTypeName typeof<float> then
boxEncoder float
elif fullname = typeof<float32>.FullName then
elif fullname = getTypeName typeof<float32> then
boxEncoder float32
// These number types require extra libraries in Fable. To prevent penalizing
// all users, extra encoders (withInt64, etc) must be passed when they're needed.
Expand All @@ -556,15 +556,15 @@ If you can't use one of these types, please pass an extra encoder.
// boxEncoder bigint
// elif fullname = typeof<decimal>.FullName then
// boxEncoder decimal
elif fullname = typeof<System.DateTime>.FullName then
elif fullname = getTypeName typeof<System.DateTime> then
boxEncoder datetime
elif fullname = typeof<System.DateTimeOffset>.FullName then
elif fullname = getTypeName typeof<System.DateTimeOffset> then
boxEncoder datetimeOffset
elif fullname = typeof<System.TimeSpan>.FullName then
elif fullname = getTypeName typeof<System.TimeSpan> then
boxEncoder timespan
elif fullname = typeof<System.Guid>.FullName then
elif fullname = getTypeName typeof<System.Guid> then
boxEncoder guid
elif fullname = typeof<obj>.FullName then
elif fullname = getTypeName typeof<obj> then
boxEncoder(fun (v: obj) -> JValue(v) :> JsonValue)
else
autoEncodeRecordsAndUnions extra caseStrategy skipNullField t
Expand Down
2 changes: 1 addition & 1 deletion src/Extra.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ let inline internal withCustomAndKey (encoder: Encoder<'Value>) (decoder: Decode
{ extra with
Hash = System.Guid.NewGuid().ToString()
Coders =
extra.Coders |> Map.add typeof<'Value>.FullName (Encode.boxEncoder encoder, Decode.boxDecoder decoder) }
extra.Coders |> Map.add (getTypeName typeof<'Value>) (Encode.boxEncoder encoder, Decode.boxDecoder decoder) }

let inline withCustom (encoder: Encoder<'Value>) (decoder: Decoder<'Value>) (extra: ExtraCoders): ExtraCoders =
withCustomAndKey encoder decoder extra
Expand Down
6 changes: 6 additions & 0 deletions src/Helpers.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Thoth.Json.Net

[<AutoOpen>]
module internal Helpers =

let getTypeName (t : System.Type) : TypeName = (t.GetGenericTypeDefinition ()).FullName |> TypeName
1 change: 1 addition & 0 deletions src/Thoth.Json.Net.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Types.fs" />
<Compile Include="Helpers.fs" />
<Compile Include="Decode.fs" />
<Compile Include="Encode.fs" />
<Compile Include="Extra.fs" />
Expand Down
5 changes: 4 additions & 1 deletion src/Types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,12 @@ type BoxedEncoder() =
abstract Encode: value: obj -> JsonValue
member this.BoxedEncoder: Encoder<obj> = this.Encode

/// Represents the `.GetGenericTypeDefinition().FullName` of a type
type TypeName = TypeName of string

type ExtraCoders =
{ Hash: string
Coders: Map<string, BoxedEncoder * BoxedDecoder> }
Coders: Map<TypeName, BoxedEncoder * BoxedDecoder> }

module internal Cache =
open System
Expand Down