Allow serde of guids (#82)

This commit is contained in:
Patrick Stevens
2024-02-06 18:50:26 +00:00
committed by GitHub
parent e453a6f07c
commit 1215834795
6 changed files with 42 additions and 5 deletions

View File

@@ -21,7 +21,7 @@ module InnerTypeWithBothJsonSerializeExtension =
let node = System.Text.Json.Nodes.JsonObject ()
do
node.Add (("it's-a-me"), System.Text.Json.Nodes.JsonValue.Create<string> input.Thing)
node.Add (("it's-a-me"), System.Text.Json.Nodes.JsonValue.Create<Guid> input.Thing)
node.Add (
"map",
@@ -245,6 +245,7 @@ module InnerTypeWithBothJsonParseExtension =
| v -> v)
.AsValue()
.GetValue<string> ()
|> System.Guid.Parse
{
Thing = Thing

View File

@@ -9,7 +9,7 @@ open System.Text.Json.Serialization
type InnerTypeWithBoth =
{
[<JsonPropertyName("it's-a-me")>]
Thing : string
Thing : Guid
Map : Map<string, Uri>
ReadOnlyDict : IReadOnlyDictionary<string, char list>
Dict : IDictionary<Uri, bool>

View File

@@ -19,7 +19,7 @@ module TestJsonSerde =
let rec innerGen (count : int) : Gen<InnerTypeWithBoth> =
gen {
let! s = Arb.generate<NonNull<string>>
let! guid = Arb.generate<Guid>
let! mapKeys = Gen.listOf Arb.generate<NonNull<string>>
let mapKeys = mapKeys |> List.map _.Get |> List.distinct
let! mapValues = Gen.listOfLength mapKeys.Length uriGen
@@ -59,7 +59,7 @@ module TestJsonSerde =
return
{
Thing = s.Get
Thing = guid
Map = map
ReadOnlyDict = readOnlyDict
Dict = dict
@@ -101,3 +101,23 @@ module TestJsonSerde =
true
property |> Prop.forAll (Arb.fromGen outerGen) |> Check.QuickThrowOnFailure
[<Test>]
let ``Guids are treated just like strings`` () =
let guidStr = "b1e7496e-6e79-4158-8579-a01de355d3b2"
let guid = Guid.Parse guidStr
let node =
{
Thing = guid
Map = Map.empty
ReadOnlyDict = readOnlyDict []
Dict = dict []
ConcreteDict = Dictionary ()
}
|> InnerTypeWithBoth.toJsonNode
node.ToJsonString ()
|> shouldEqual (
sprintf """{"it\u0027s-a-me":"%s","map":{},"readOnlyDict":{},"dict":{},"concreteDict":{}}""" guidStr
)

View File

@@ -467,6 +467,15 @@ module internal SynTypePatterns =
| _ -> None
| _ -> None
let (|Guid|_|) (fieldType : SynType) : unit option =
match fieldType with
| SynType.LongIdent ident ->
match ident.LongIdent |> List.map (fun i -> i.idText) with
| [ "System" ; "Guid" ]
| [ "Guid" ] -> Some ()
| _ -> None
| _ -> None
let (|HttpResponseMessage|_|) (fieldType : SynType) : unit option =
match fieldType with
| SynType.LongIdent ident ->

View File

@@ -211,6 +211,12 @@ module internal JsonParseGenerator =
node
|> asValueGetValue propertyName "string"
|> SynExpr.pipeThroughFunction (SynExpr.CreateLongIdent (SynLongIdent.Create [ "System" ; "Uri" ]))
| Guid ->
node
|> asValueGetValue propertyName "string"
|> SynExpr.pipeThroughFunction (
SynExpr.CreateLongIdent (SynLongIdent.Create [ "System" ; "Guid" ; "Parse" ])
)
| DateTime ->
node
|> asValueGetValue propertyName "string"

View File

@@ -43,8 +43,9 @@ module internal JsonSerializeGenerator =
| DateTime
| NumberType _
| PrimitiveType _
| Guid
| Uri ->
// JsonValue.Create<{type}>
// JsonValue.Create<type>
SynExpr.TypeApp (
SynExpr.CreateLongIdent (
SynLongIdent.Create [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonValue" ; "Create" ]