Be compatible with <Nullable>enable</Nullable> (#369)

This commit is contained in:
Patrick Stevens
2025-04-21 18:43:52 +01:00
committed by GitHub
parent 0fe97da788
commit 425d5313b4
14 changed files with 27303 additions and 9336 deletions

View File

@@ -1,5 +1,15 @@
Notable changes are recorded here.
# WoofWare.Myriad.Plugins 7.0.1
All generators should now be compatible with `<Nullable>enable</Nullable>`.
**Please test the results and let me know of unexpected failures.**
There are a number of heuristics in this code, because:
* `System.Text.Json.Nodes` is an unfathomably weird API which simply requires us to make educated guesses about whether a user-provided type is supposed to be nullable, despite this being irrelevant to the operation of `System.Text.Json`;
* Some types (like `Uri` and `String`) have `ToString` methods which can't return `null`, but in general `Object.ToString` can of course return `null`, and as far as I can tell there is simply no way to know from the source alone whether a given type will have a nullable `ToString`.
# WoofWare.Myriad.Plugins 6.0.1
The `ArgParser` generator's type signatures have changed.

View File

@@ -4,6 +4,7 @@
<TargetFramework>net9.0</TargetFramework>
<IsPackable>false</IsPackable>
<OtherFlags>--reflectionfree $(OtherFlags)</OtherFlags>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<MyriadSdkGenerator Include="$(MSBuildThisFileDirectory)..\WoofWare.Myriad.Plugins\bin\$(Configuration)\net6.0\WoofWare.Myriad.Plugins.dll"/>

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,24 @@ module internal InternalTypeNotExtensionSerial =
/// Serialize to a JSON node
let toJsonNode (input : InternalTypeNotExtensionSerial) : System.Text.Json.Nodes.JsonNode =
let node = System.Text.Json.Nodes.JsonObject ()
do node.Add ((Literals.something), (input.InternalThing2 |> System.Text.Json.Nodes.JsonValue.Create<string>))
do
node.Add (
(Literals.something),
(input.InternalThing2
|> (fun field ->
let field = System.Text.Json.Nodes.JsonValue.Create<string> field
(match field with
| null ->
raise (
System.ArgumentNullException
"Expected type string to be non-null, but received a null value when serialising"
)
| field -> field)
))
)
node :> _
namespace ConsumePlugin
@@ -29,7 +46,24 @@ module internal InternalTypeExtensionJsonSerializeExtension =
/// Serialize to a JSON node
static member toJsonNode (input : InternalTypeExtension) : System.Text.Json.Nodes.JsonNode =
let node = System.Text.Json.Nodes.JsonObject ()
do node.Add ((Literals.something), (input.ExternalThing |> System.Text.Json.Nodes.JsonValue.Create<string>))
do
node.Add (
(Literals.something),
(input.ExternalThing
|> (fun field ->
let field = System.Text.Json.Nodes.JsonValue.Create<string> field
(match field with
| null ->
raise (
System.ArgumentNullException
"Expected type string to be non-null, but received a null value when serialising"
)
| field -> field)
))
)
node :> _
namespace ConsumePlugin
@@ -40,16 +74,14 @@ module InnerType =
/// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : InnerType =
let arg_0 =
(match node.[(Literals.something)] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
match node.[(Literals.something)] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
)
)
| Some node -> node.AsValue().GetValue<System.String> ()
{
Thing = arg_0
@@ -62,91 +94,97 @@ module JsonRecordType =
/// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : JsonRecordType =
let arg_5 =
(match node.["f"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("f")
)
)
| v -> v)
.AsArray ()
|> Seq.map (fun elt ->
(match elt with
| null -> raise (System.ArgumentNullException ())
| elt -> elt.AsValue().GetValue<System.Int32> ())
)
|> Array.ofSeq
match node.["f"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("f")
)
)
| Some node ->
node.AsArray ()
|> Seq.map (fun elt ->
(match elt with
| null ->
raise (
System.ArgumentNullException
"Expected element of array (element type int32) to be non-null, but found a null element"
)
| elt -> elt.AsValue().GetValue<System.Int32> ())
)
|> Array.ofSeq
let arg_4 =
(match node.["e"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("e")
)
)
| v -> v)
.AsArray ()
|> Seq.map (fun elt ->
(match elt with
| null -> raise (System.ArgumentNullException ())
| elt -> elt.AsValue().GetValue<System.String> ())
)
|> Array.ofSeq
match node.["e"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("e")
)
)
| Some node ->
node.AsArray ()
|> Seq.map (fun elt ->
(match elt with
| null ->
raise (
System.ArgumentNullException
"Expected element of array (element type string) to be non-null, but found a null element"
)
| elt -> elt.AsValue().GetValue<System.String> ())
)
|> Array.ofSeq
let arg_3 =
InnerType.jsonParse (
match node.["d"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("d")
)
match node.["d"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("d")
)
| v -> v
)
)
| Some node -> InnerType.jsonParse node
let arg_2 =
(match node.["hi"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("hi")
)
)
| v -> v)
.AsArray ()
|> Seq.map (fun elt ->
(match elt with
| null -> raise (System.ArgumentNullException ())
| elt -> elt.AsValue().GetValue<System.Int32> ())
)
|> List.ofSeq
match node.["hi"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("hi")
)
)
| Some node ->
node.AsArray ()
|> Seq.map (fun elt ->
(match elt with
| null ->
raise (
System.ArgumentNullException
"Expected element of array (element type int32) to be non-null, but found a null element"
)
| elt -> elt.AsValue().GetValue<System.Int32> ())
)
|> List.ofSeq
let arg_1 =
(match node.["another-thing"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("another-thing")
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
match node.["another-thing"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("another-thing")
)
)
| Some node -> node.AsValue().GetValue<System.String> ()
let arg_0 =
(match node.["a"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("a")
)
)
| v -> v)
.AsValue()
.GetValue<System.Int32> ()
match node.["a"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("a")
)
)
| Some node -> node.AsValue().GetValue<System.Int32> ()
{
A = arg_0
@@ -164,16 +202,14 @@ module internal InternalTypeNotExtension =
/// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : InternalTypeNotExtension =
let arg_0 =
(match node.[(Literals.something)] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
match node.[(Literals.something)] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
)
)
| Some node -> node.AsValue().GetValue<System.String> ()
{
InternalThing = arg_0
@@ -189,16 +225,14 @@ module internal InternalTypeExtensionJsonParseExtension =
/// Parse from a JSON node.
static member jsonParse (node : System.Text.Json.Nodes.JsonNode) : InternalTypeExtension =
let arg_0 =
(match node.[(Literals.something)] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
match node.[(Literals.something)] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ((Literals.something))
)
)
| Some node -> node.AsValue().GetValue<System.String> ()
{
ExternalThing = arg_0
@@ -213,248 +247,215 @@ module ToGetExtensionMethodJsonParseExtension =
/// Parse from a JSON node.
static member jsonParse (node : System.Text.Json.Nodes.JsonNode) : ToGetExtensionMethod =
let arg_20 = System.Numerics.BigInteger.Parse (node.["whiskey"].ToJsonString ())
let arg_20 =
match node.["whiskey"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("whiskey")
)
)
| Some node -> System.Numerics.BigInteger.Parse (node.ToJsonString ())
let arg_19 =
(match node.["victor"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("victor")
)
)
| v -> v)
.AsValue()
.GetValue<System.Char> ()
match node.["victor"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("victor")
)
)
| Some node -> node.AsValue().GetValue<System.Char> ()
let arg_18 =
(match node.["uniform"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("uniform")
)
)
| v -> v)
.AsValue()
.GetValue<System.Decimal> ()
match node.["uniform"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("uniform")
)
)
| Some node -> node.AsValue().GetValue<System.Decimal> ()
let arg_17 =
(match node.["tango"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("tango")
)
)
| v -> v)
.AsValue()
.GetValue<System.SByte> ()
match node.["tango"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("tango")
)
)
| Some node -> node.AsValue().GetValue<System.SByte> ()
let arg_16 =
(match node.["quebec"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("quebec")
)
)
| v -> v)
.AsValue()
.GetValue<System.Byte> ()
match node.["quebec"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("quebec")
)
)
| Some node -> node.AsValue().GetValue<System.Byte> ()
let arg_15 =
(match node.["papa"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("papa")
)
)
| v -> v)
.AsValue()
.GetValue<System.Byte> ()
match node.["papa"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("papa")
)
)
| Some node -> node.AsValue().GetValue<System.Byte> ()
let arg_14 =
(match node.["oscar"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("oscar")
)
)
| v -> v)
.AsValue()
.GetValue<System.SByte> ()
match node.["oscar"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("oscar")
)
)
| Some node -> node.AsValue().GetValue<System.SByte> ()
let arg_13 =
(match node.["november"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("november")
)
)
| v -> v)
.AsValue()
.GetValue<System.UInt16> ()
match node.["november"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("november")
)
)
| Some node -> node.AsValue().GetValue<System.UInt16> ()
let arg_12 =
(match node.["mike"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("mike")
)
)
| v -> v)
.AsValue()
.GetValue<System.Int16> ()
match node.["mike"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("mike")
)
)
| Some node -> node.AsValue().GetValue<System.Int16> ()
let arg_11 =
(match node.["lima"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lima")
)
)
| v -> v)
.AsValue()
.GetValue<System.UInt32> ()
match node.["lima"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lima")
)
)
| Some node -> node.AsValue().GetValue<System.UInt32> ()
let arg_10 =
(match node.["kilo"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("kilo")
)
)
| v -> v)
.AsValue()
.GetValue<System.Int32> ()
match node.["kilo"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("kilo")
)
)
| Some node -> node.AsValue().GetValue<System.Int32> ()
let arg_9 =
(match node.["juliette"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("juliette")
)
)
| v -> v)
.AsValue()
.GetValue<System.UInt32> ()
match node.["juliette"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("juliette")
)
)
| Some node -> node.AsValue().GetValue<System.UInt32> ()
let arg_8 =
(match node.["india"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("india")
)
)
| v -> v)
.AsValue()
.GetValue<System.Int32> ()
match node.["india"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("india")
)
)
| Some node -> node.AsValue().GetValue<System.Int32> ()
let arg_7 =
(match node.["hotel"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("hotel")
)
)
| v -> v)
.AsValue()
.GetValue<System.UInt64> ()
match node.["hotel"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("hotel")
)
)
| Some node -> node.AsValue().GetValue<System.UInt64> ()
let arg_6 =
(match node.["golf"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("golf")
)
)
| v -> v)
.AsValue()
.GetValue<System.Int64> ()
match node.["golf"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("golf")
)
)
| Some node -> node.AsValue().GetValue<System.Int64> ()
let arg_5 =
(match node.["foxtrot"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("foxtrot")
)
)
| v -> v)
.AsValue()
.GetValue<System.Double> ()
match node.["foxtrot"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("foxtrot")
)
)
| Some node -> node.AsValue().GetValue<System.Double> ()
let arg_4 =
(match node.["echo"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("echo")
)
)
| v -> v)
.AsValue()
.GetValue<System.Single> ()
match node.["echo"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("echo")
)
)
| Some node -> node.AsValue().GetValue<System.Single> ()
let arg_3 =
(match node.["delta"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("delta")
)
)
| v -> v)
.AsValue()
.GetValue<System.Single> ()
match node.["delta"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("delta")
)
)
| Some node -> node.AsValue().GetValue<System.Single> ()
let arg_2 =
(match node.["charlie"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("charlie")
)
)
| v -> v)
.AsValue()
.GetValue<System.Double> ()
match node.["charlie"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("charlie")
)
)
| Some node -> node.AsValue().GetValue<System.Double> ()
let arg_1 =
(match node.["bravo"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("bravo")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
|> System.Uri
match node.["bravo"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("bravo")
)
)
| Some node -> node.AsValue().GetValue<string> () |> System.Uri
let arg_0 =
(match node.["alpha"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("alpha")
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
match node.["alpha"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("alpha")
)
)
| Some node -> node.AsValue().GetValue<System.String> ()
{
Alpha = arg_0

File diff suppressed because it is too large Load Diff

View File

@@ -48,11 +48,24 @@ module PureGymApi =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type Gym list"
)
| jsonNode -> jsonNode)
return
jsonNode.AsArray ()
|> Seq.map (fun elt ->
(match elt with
| null -> raise (System.ArgumentNullException ())
| null ->
raise (
System.ArgumentNullException
"Expected element of array (element type Gym) to be non-null, but found a null element"
)
| elt -> Gym.jsonParse elt)
)
|> List.ofSeq
@@ -89,6 +102,15 @@ module PureGymApi =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type GymAttendance"
)
| jsonNode -> jsonNode)
return GymAttendance.jsonParse jsonNode
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
@@ -123,6 +145,15 @@ module PureGymApi =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type GymAttendance"
)
| jsonNode -> jsonNode)
return GymAttendance.jsonParse jsonNode
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
@@ -153,6 +184,15 @@ module PureGymApi =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type Member"
)
| jsonNode -> jsonNode)
return Member.jsonParse jsonNode
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
@@ -186,6 +226,15 @@ module PureGymApi =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type Gym"
)
| jsonNode -> jsonNode)
return Gym.jsonParse jsonNode
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
@@ -216,6 +265,15 @@ module PureGymApi =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type MemberActivityDto"
)
| jsonNode -> jsonNode)
return MemberActivityDto.jsonParse jsonNode
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
@@ -246,6 +304,15 @@ module PureGymApi =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type UriThing"
)
| jsonNode -> jsonNode)
return UriThing.jsonParse jsonNode
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
@@ -273,23 +340,42 @@ module PureGymApi =
foo
|> (fun field ->
match field with
| None -> null :> System.Text.Json.Nodes.JsonNode
| None -> None
| Some field ->
((fun field ->
let ret = System.Text.Json.Nodes.JsonObject ()
(field
|> (fun field ->
let ret = System.Text.Json.Nodes.JsonObject ()
for (KeyValue (key, value)) in field do
ret.Add (
key.ToString (),
System.Text.Json.Nodes.JsonValue.Create<string> value
)
for (KeyValue (key, value)) in field do
let key = key.ToString ()
ret
)
field)
ret.Add (
key,
(fun field ->
let field =
System.Text.Json.Nodes.JsonValue.Create<string> field
(match field with
| null ->
raise (
System.ArgumentNullException
"Expected type string to be non-null, but received a null value when serialising"
)
| field -> field)
)
value
)
ret
))
:> System.Text.Json.Nodes.JsonNode
|> Some
)
|> (fun node ->
match node with
| None -> "null"
| Some node -> node.ToJsonString ()
)
|> (fun node -> if isNull node then "null" else node.ToJsonString ())
)
do httpMessage.Content <- queryParams
@@ -301,15 +387,25 @@ module PureGymApi =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode = jsonNode |> Option.ofObj
return
match jsonNode with
| null -> None
| v ->
| None -> None
| Some v ->
v.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key)
let value = (kvp.Value).AsValue().GetValue<System.String> ()
key, value
let value = kvp.Value
key,
(match value with
| null ->
raise (
System.ArgumentNullException
"Expected dictionary value of type string to be non-null, but it was null"
)
| value -> value.AsValue().GetValue<System.String> ())
)
|> Map.ofSeq
|> Some
@@ -353,6 +449,15 @@ module PureGymApi =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type Sessions"
)
| jsonNode -> jsonNode)
return Sessions.jsonParse jsonNode
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
@@ -394,6 +499,15 @@ module PureGymApi =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type Sessions"
)
| jsonNode -> jsonNode)
return Sessions.jsonParse jsonNode
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
@@ -553,9 +667,7 @@ module PureGymApi =
let queryParams =
new System.Net.Http.StringContent (
user
|> PureGym.Member.toJsonNode
|> (fun node -> if isNull node then "null" else node.ToJsonString ())
user |> PureGym.Member.toJsonNode |> (fun node -> node.ToJsonString ())
)
do httpMessage.Content <- queryParams
@@ -587,8 +699,18 @@ module PureGymApi =
let queryParams =
new System.Net.Http.StringContent (
user
|> System.Text.Json.Nodes.JsonValue.Create<Uri>
|> (fun node -> if isNull node then "null" else node.ToJsonString ())
|> (fun field ->
let field = System.Text.Json.Nodes.JsonValue.Create<Uri> field
(match field with
| null ->
raise (
System.ArgumentNullException
"Expected type URI to be non-null, but received a null value when serialising"
)
| field -> field)
)
|> (fun node -> node.ToJsonString ())
)
do httpMessage.Content <- queryParams
@@ -620,8 +742,18 @@ module PureGymApi =
let queryParams =
new System.Net.Http.StringContent (
user
|> System.Text.Json.Nodes.JsonValue.Create<int>
|> (fun node -> if isNull node then "null" else node.ToJsonString ())
|> (fun field ->
let field = System.Text.Json.Nodes.JsonValue.Create<int> field
(match field with
| null ->
raise (
System.ArgumentNullException
"Expected type int32 to be non-null, but received a null value when serialising"
)
| field -> field)
)
|> (fun node -> node.ToJsonString ())
)
do httpMessage.Content <- queryParams
@@ -885,6 +1017,15 @@ module PureGymApi =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type Response<MemberActivityDto>"
)
| jsonNode -> jsonNode)
return
new RestEase.Response<_> (
responseString,
@@ -921,6 +1062,15 @@ module PureGymApi =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type RestEase.Response<MemberActivityDto>"
)
| jsonNode -> jsonNode)
return
new RestEase.Response<_> (
responseString,
@@ -957,6 +1107,15 @@ module PureGymApi =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type Response<MemberActivityDto>"
)
| jsonNode -> jsonNode)
return
new RestEase.Response<_> (
responseString,
@@ -993,6 +1152,15 @@ module PureGymApi =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type RestEase.Response<MemberActivityDto>"
)
| jsonNode -> jsonNode)
return
new RestEase.Response<_> (
responseString,

File diff suppressed because it is too large Load Diff

View File

@@ -13,151 +13,147 @@ module JwtVaultAuthResponse =
/// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : JwtVaultAuthResponse =
let arg_10 =
(match node.["num_uses"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("num_uses")
)
)
| v -> v)
.AsValue()
.GetValue<System.Int32> ()
match node.["num_uses"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("num_uses")
)
)
| Some node -> node.AsValue().GetValue<System.Int32> ()
let arg_9 =
(match node.["orphan"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("orphan")
)
)
| v -> v)
.AsValue()
.GetValue<System.Boolean> ()
match node.["orphan"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("orphan")
)
)
| Some node -> node.AsValue().GetValue<System.Boolean> ()
let arg_8 =
(match node.["entity_id"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("entity_id")
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
match node.["entity_id"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("entity_id")
)
)
| Some node -> node.AsValue().GetValue<System.String> ()
let arg_7 =
(match node.["token_type"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("token_type")
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
match node.["token_type"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("token_type")
)
)
| Some node -> node.AsValue().GetValue<System.String> ()
let arg_6 =
(match node.["renewable"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("renewable")
)
)
| v -> v)
.AsValue()
.GetValue<System.Boolean> ()
match node.["renewable"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("renewable")
)
)
| Some node -> node.AsValue().GetValue<System.Boolean> ()
let arg_5 =
(match node.["lease_duration"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
)
)
| v -> v)
.AsValue()
.GetValue<System.Int32> ()
match node.["lease_duration"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
)
)
| Some node -> node.AsValue().GetValue<System.Int32> ()
let arg_4 =
(match node.["identity_policies"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("identity_policies")
)
)
| v -> v)
.AsArray ()
|> Seq.map (fun elt ->
(match elt with
| null -> raise (System.ArgumentNullException ())
| elt -> elt.AsValue().GetValue<System.String> ())
)
|> List.ofSeq
match node.["identity_policies"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("identity_policies")
)
)
| Some node ->
node.AsArray ()
|> Seq.map (fun elt ->
(match elt with
| null ->
raise (
System.ArgumentNullException
"Expected element of array (element type string) to be non-null, but found a null element"
)
| elt -> elt.AsValue().GetValue<System.String> ())
)
|> List.ofSeq
let arg_3 =
(match node.["token_policies"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("token_policies")
)
)
| v -> v)
.AsArray ()
|> Seq.map (fun elt ->
(match elt with
| null -> raise (System.ArgumentNullException ())
| elt -> elt.AsValue().GetValue<System.String> ())
)
|> List.ofSeq
match node.["token_policies"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("token_policies")
)
)
| Some node ->
node.AsArray ()
|> Seq.map (fun elt ->
(match elt with
| null ->
raise (
System.ArgumentNullException
"Expected element of array (element type string) to be non-null, but found a null element"
)
| elt -> elt.AsValue().GetValue<System.String> ())
)
|> List.ofSeq
let arg_2 =
(match node.["policies"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("policies")
)
)
| v -> v)
.AsArray ()
|> Seq.map (fun elt ->
(match elt with
| null -> raise (System.ArgumentNullException ())
| elt -> elt.AsValue().GetValue<System.String> ())
)
|> List.ofSeq
match node.["policies"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("policies")
)
)
| Some node ->
node.AsArray ()
|> Seq.map (fun elt ->
(match elt with
| null ->
raise (
System.ArgumentNullException
"Expected element of array (element type string) to be non-null, but found a null element"
)
| elt -> elt.AsValue().GetValue<System.String> ())
)
|> List.ofSeq
let arg_1 =
(match node.["accessor"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("accessor")
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
match node.["accessor"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("accessor")
)
)
| Some node -> node.AsValue().GetValue<System.String> ()
let arg_0 =
(match node.["client_token"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("client_token")
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
match node.["client_token"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("client_token")
)
)
| Some node -> node.AsValue().GetValue<System.String> ()
{
ClientToken = arg_0
@@ -180,64 +176,54 @@ module JwtVaultResponse =
/// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : JwtVaultResponse =
let arg_4 =
JwtVaultAuthResponse.jsonParse (
match node.["auth"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("auth")
)
match node.["auth"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("auth")
)
| v -> v
)
)
| Some node -> JwtVaultAuthResponse.jsonParse node
let arg_3 =
(match node.["lease_duration"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
)
)
| v -> v)
.AsValue()
.GetValue<System.Int32> ()
match node.["lease_duration"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
)
)
| Some node -> node.AsValue().GetValue<System.Int32> ()
let arg_2 =
(match node.["renewable"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("renewable")
)
)
| v -> v)
.AsValue()
.GetValue<System.Boolean> ()
match node.["renewable"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("renewable")
)
)
| Some node -> node.AsValue().GetValue<System.Boolean> ()
let arg_1 =
(match node.["lease_id"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lease_id")
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
match node.["lease_id"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lease_id")
)
)
| Some node -> node.AsValue().GetValue<System.String> ()
let arg_0 =
(match node.["request_id"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("request_id")
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
match node.["request_id"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("request_id")
)
)
| Some node -> node.AsValue().GetValue<System.String> ()
{
RequestId = arg_0
@@ -254,190 +240,246 @@ module JwtSecretResponse =
/// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : JwtSecretResponse =
let arg_11 =
(match node.["data8"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data8")
)
)
| v -> v)
.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key)
let value = (kvp.Value).AsValue().GetValue<string> () |> System.Uri
key, value
)
|> Seq.map System.Collections.Generic.KeyValuePair
|> System.Collections.Generic.Dictionary
match node.["data8"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data8")
)
)
| Some node ->
node.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key)
let value = kvp.Value
key,
(match value with
| null ->
raise (
System.ArgumentNullException
"Expected dictionary value of type URI to be non-null, but it was null"
)
| value -> value.AsValue().GetValue<string> () |> System.Uri)
)
|> Seq.map System.Collections.Generic.KeyValuePair
|> System.Collections.Generic.Dictionary
let arg_10 =
(match node.["data7"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data7")
)
)
| v -> v)
.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key)
let value = (kvp.Value).AsValue().GetValue<System.Int32> ()
key, value
)
|> Map.ofSeq
match node.["data7"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data7")
)
)
| Some node ->
node.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key)
let value = kvp.Value
key,
(match value with
| null ->
raise (
System.ArgumentNullException
"Expected dictionary value of type int32 to be non-null, but it was null"
)
| value -> value.AsValue().GetValue<System.Int32> ())
)
|> Map.ofSeq
let arg_9 =
(match node.["data6"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data6")
)
)
| v -> v)
.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key) |> System.Uri
let value = (kvp.Value).AsValue().GetValue<System.String> ()
key, value
)
|> dict
match node.["data6"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data6")
)
)
| Some node ->
node.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key) |> System.Uri
let value = kvp.Value
key,
(match value with
| null ->
raise (
System.ArgumentNullException
"Expected dictionary value of type string to be non-null, but it was null"
)
| value -> value.AsValue().GetValue<System.String> ())
)
|> dict
let arg_8 =
(match node.["data5"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data5")
)
)
| v -> v)
.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key) |> System.Uri
let value = (kvp.Value).AsValue().GetValue<System.String> ()
key, value
)
|> readOnlyDict
match node.["data5"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data5")
)
)
| Some node ->
node.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key) |> System.Uri
let value = kvp.Value
key,
(match value with
| null ->
raise (
System.ArgumentNullException
"Expected dictionary value of type string to be non-null, but it was null"
)
| value -> value.AsValue().GetValue<System.String> ())
)
|> readOnlyDict
let arg_7 =
(match node.["data4"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data4")
)
)
| v -> v)
.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key)
let value = (kvp.Value).AsValue().GetValue<System.String> ()
key, value
)
|> Map.ofSeq
match node.["data4"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data4")
)
)
| Some node ->
node.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key)
let value = kvp.Value
key,
(match value with
| null ->
raise (
System.ArgumentNullException
"Expected dictionary value of type string to be non-null, but it was null"
)
| value -> value.AsValue().GetValue<System.String> ())
)
|> Map.ofSeq
let arg_6 =
(match node.["data3"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data3")
)
)
| v -> v)
.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key)
let value = (kvp.Value).AsValue().GetValue<System.String> ()
key, value
)
|> Seq.map System.Collections.Generic.KeyValuePair
|> System.Collections.Generic.Dictionary
match node.["data3"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data3")
)
)
| Some node ->
node.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key)
let value = kvp.Value
key,
(match value with
| null ->
raise (
System.ArgumentNullException
"Expected dictionary value of type string to be non-null, but it was null"
)
| value -> value.AsValue().GetValue<System.String> ())
)
|> Seq.map System.Collections.Generic.KeyValuePair
|> System.Collections.Generic.Dictionary
let arg_5 =
(match node.["data2"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data2")
)
)
| v -> v)
.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key)
let value = (kvp.Value).AsValue().GetValue<System.String> ()
key, value
)
|> dict
match node.["data2"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data2")
)
)
| Some node ->
node.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key)
let value = kvp.Value
key,
(match value with
| null ->
raise (
System.ArgumentNullException
"Expected dictionary value of type string to be non-null, but it was null"
)
| value -> value.AsValue().GetValue<System.String> ())
)
|> dict
let arg_4 =
(match node.["data"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data")
)
)
| v -> v)
.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key)
let value = (kvp.Value).AsValue().GetValue<System.String> ()
key, value
)
|> readOnlyDict
match node.["data"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("data")
)
)
| Some node ->
node.AsObject ()
|> Seq.map (fun kvp ->
let key = (kvp.Key)
let value = kvp.Value
key,
(match value with
| null ->
raise (
System.ArgumentNullException
"Expected dictionary value of type string to be non-null, but it was null"
)
| value -> value.AsValue().GetValue<System.String> ())
)
|> readOnlyDict
let arg_3 =
(match node.["lease_duration"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
)
)
| v -> v)
.AsValue()
.GetValue<System.Int32> ()
match node.["lease_duration"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lease_duration")
)
)
| Some node -> node.AsValue().GetValue<System.Int32> ()
let arg_2 =
(match node.["renewable"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("renewable")
)
)
| v -> v)
.AsValue()
.GetValue<System.Boolean> ()
match node.["renewable"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("renewable")
)
)
| Some node -> node.AsValue().GetValue<System.Boolean> ()
let arg_1 =
(match node.["lease_id"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lease_id")
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
match node.["lease_id"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lease_id")
)
)
| Some node -> node.AsValue().GetValue<System.String> ()
let arg_0 =
(match node.["request_id"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("request_id")
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
match node.["request_id"] |> Option.ofObj with
| None ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("request_id")
)
)
| Some node -> node.AsValue().GetValue<System.String> ()
{
RequestId = arg_0
@@ -508,6 +550,15 @@ module VaultClient =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type JwtSecretResponse"
)
| jsonNode -> jsonNode)
return JwtSecretResponse.jsonParse jsonNode
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
@@ -544,6 +595,15 @@ module VaultClient =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type JwtVaultResponse"
)
| jsonNode -> jsonNode)
return JwtVaultResponse.jsonParse jsonNode
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
@@ -602,6 +662,15 @@ module VaultClientNonExtensionMethod =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type JwtSecretResponse"
)
| jsonNode -> jsonNode)
return JwtSecretResponse.jsonParse jsonNode
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
@@ -638,6 +707,15 @@ module VaultClientNonExtensionMethod =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type JwtVaultResponse"
)
| jsonNode -> jsonNode)
return JwtVaultResponse.jsonParse jsonNode
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
@@ -699,6 +777,15 @@ module VaultClientExtensionMethodHttpClientExtension =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type JwtSecretResponse"
)
| jsonNode -> jsonNode)
return JwtSecretResponse.jsonParse jsonNode
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))
@@ -735,6 +822,15 @@ module VaultClientExtensionMethodHttpClientExtension =
System.Text.Json.Nodes.JsonNode.ParseAsync (responseStream, cancellationToken = ct)
|> Async.AwaitTask
let jsonNode =
(match jsonNode with
| null ->
raise (
System.ArgumentNullException
"Response from server was the JSON null object; expected a non-nullable type JwtVaultResponse"
)
| jsonNode -> jsonNode)
return JwtVaultResponse.jsonParse jsonNode
}
|> (fun a -> Async.StartAsTask (a, ?cancellationToken = ct))

View File

@@ -1,6 +1,5 @@
namespace WoofWare.Myriad.Plugins
open System.IO
open System.Net.Http
open Fantomas.FCS.Syntax
open WoofWare.Whippet.Fantomas
@@ -14,17 +13,6 @@ type internal HttpClientGeneratorOutputSpec =
module internal HttpClientGenerator =
open Fantomas.FCS.Text.Range
let outputFile = FileInfo "/tmp/output.txt"
// do
// use _ = File.Create outputFile.FullName
// ()
let log (line : string) =
// use w = outputFile.AppendText ()
// w.WriteLine line
()
[<RequireQualifiedAccess>]
type PathSpec =
| Verbatim of string
@@ -409,30 +397,59 @@ module internal HttpClientGenerator =
| String -> SynExpr.createIdent "responseString"
| Stream -> SynExpr.createIdent "responseStream"
| RestEaseResponseType contents ->
let deserialiser =
JsonParseGenerator.parseNode
match JsonNodeWithNullability.Identify contents with
| CannotBeNull ->
let deserialiser =
JsonParseGenerator.parseNonNullableNode
None
JsonParseGenerator.JsonParseOption.None
contents
(SynExpr.createIdent "jsonNode")
|> SynExpr.paren
|> SynExpr.createThunk
// new RestEase.Response (content : string, response : HttpResponseMessage, deserialiser : unit -> 'T)
SynExpr.createNew
(SynType.app' (SynType.createLongIdent' [ "RestEase" ; "Response" ]) [ SynType.Anon range0 ])
(SynExpr.tupleNoParen
[
SynExpr.createIdent "responseString"
SynExpr.createIdent "response"
deserialiser
])
| Nullable ->
let deserialiser =
JsonParseGenerator.parseNullableNode
None
JsonParseGenerator.JsonParseOption.None
contents
(SynExpr.createIdent "jsonNode")
|> SynExpr.paren
|> SynExpr.createThunk
// new RestEase.Response (content : string, response : HttpResponseMessage, deserialiser : unit -> 'T)
SynExpr.createNew
(SynType.app' (SynType.createLongIdent' [ "RestEase" ; "Response" ]) [ SynType.Anon range0 ])
(SynExpr.tupleNoParen
[
SynExpr.createIdent "responseString"
SynExpr.createIdent "response"
deserialiser
])
| retType ->
match JsonNodeWithNullability.Identify retType with
| Nullable ->
JsonParseGenerator.parseNullableNode
None
JsonParseGenerator.JsonParseOption.None
contents
retType
(SynExpr.createIdent "jsonNode")
| CannotBeNull ->
JsonParseGenerator.parseNonNullableNode
None
JsonParseGenerator.JsonParseOption.None
retType
(SynExpr.createIdent "jsonNode")
|> SynExpr.paren
|> SynExpr.createThunk
// new RestEase.Response (content : string, response : HttpResponseMessage, deserialiser : unit -> 'T)
SynExpr.createNew
(SynType.app' (SynType.createLongIdent' [ "RestEase" ; "Response" ]) [ SynType.Anon range0 ])
(SynExpr.tupleNoParen
[
SynExpr.createIdent "responseString"
SynExpr.createIdent "response"
deserialiser
])
| retType ->
JsonParseGenerator.parseNode
None
JsonParseGenerator.JsonParseOption.None
retType
(SynExpr.createIdent "jsonNode")
let contentTypeHeader, memberHeaders =
info.Headers
@@ -505,23 +522,45 @@ module internal HttpClientGenerator =
)
]
| BodyParamMethods.Serialise ty ->
let isNullable =
match JsonNodeWithNullability.Identify ty with
| CannotBeNull -> false
| Nullable -> true
[
Let (
"queryParams",
createStringContent (
SynExpr.createIdent' bodyParamName
|> SynExpr.pipeThroughFunction (fst (JsonSerializeGenerator.serializeNode ty))
|> SynExpr.pipeThroughFunction (
fst (
(if isNullable then
JsonSerializeGenerator.serializeNodeNullable
else
JsonSerializeGenerator.serializeNodeNonNullable)
ty
)
)
|> SynExpr.pipeThroughFunction (
SynExpr.createLambda
"node"
(SynExpr.ifThenElse
(SynExpr.applyFunction
(SynExpr.createIdent "isNull")
(SynExpr.createIdent "node"))
(SynExpr.applyFunction
(SynExpr.createLongIdent [ "node" ; "ToJsonString" ])
(SynExpr.CreateConst ()))
(SynExpr.CreateConst "null"))
(if isNullable then
SynExpr.createMatch
(SynExpr.createIdent "node")
[
SynMatchClause.create
(SynPat.named "None")
(SynExpr.CreateConst "null")
SynMatchClause.create
(SynPat.nameWithArgs "Some" [ SynPat.named "node" ])
(SynExpr.applyFunction
(SynExpr.createLongIdent [ "node" ; "ToJsonString" ])
(SynExpr.CreateConst ()))
]
else
(SynExpr.applyFunction
(SynExpr.createLongIdent [ "node" ; "ToJsonString" ])
(SynExpr.CreateConst ())))
)
)
)
@@ -568,6 +607,24 @@ module internal HttpClientGenerator =
)
)
let jsonNodeWithoutNull =
match JsonNodeWithNullability.Identify info.TaskReturnType with
| Nullable ->
Let (
"jsonNode",
SynExpr.createIdent "jsonNode"
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
)
| CannotBeNull ->
Let (
"jsonNode",
JsonSerializeGenerator.assertNotNull
(Ident.create "jsonNode")
(SynExpr.CreateConst
$"Response from server was the JSON null object; expected a non-nullable type %s{SynType.toHumanReadableString info.TaskReturnType}")
(SynExpr.createIdent "jsonNode")
)
let setVariableHeaders =
variableHeaders
|> List.map (fun (headerName, callToGetValue) ->
@@ -642,6 +699,7 @@ module internal HttpClientGenerator =
yield responseString
yield responseStream
yield jsonNode
yield jsonNodeWithoutNull
| String -> yield responseString
| Stream -> yield responseStream
| UnitType ->
@@ -650,6 +708,7 @@ module internal HttpClientGenerator =
| _ ->
yield responseStream
yield jsonNode
yield jsonNodeWithoutNull
]
|> SynExpr.createCompExpr "async" returnExpr
|> SynExpr.startAsTask cancellationTokenArg

View File

@@ -40,26 +40,12 @@ module internal JsonParseGenerator =
|> SynExpr.applyFunction (SynExpr.createIdent "raise")
[
SynMatchClause.create SynPat.createNull raiseExpr
SynMatchClause.create (SynPat.named "v") (SynExpr.createIdent "v")
SynMatchClause.create (SynPat.named "None") raiseExpr
SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "v" ]) (SynExpr.createIdent "v")
]
|> SynExpr.createMatch indexed
|> SynExpr.paren
let assertNotNull (boundIdent : Ident) (body : SynExpr) : SynExpr =
let raiseExpr =
SynExpr.CreateConst ()
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "ArgumentNullException" ])
|> SynExpr.paren
|> SynExpr.applyFunction (SynExpr.createIdent "raise")
[
SynMatchClause.create SynPat.createNull raiseExpr
SynMatchClause.create (SynPat.namedI boundIdent) body
]
|> SynExpr.createMatch (SynExpr.createIdent' boundIdent)
|> SynExpr.paren
/// {node}.AsValue().GetValue<{typeName}> ()
/// If `propertyName` is Some, uses `assertPropertyExists {node}` instead of `{node}`.
let asValueGetValue (propertyName : SynExpr option) (typeName : string) (node : SynExpr) : SynExpr =
@@ -96,6 +82,7 @@ module internal JsonParseGenerator =
/// |> {collectionType}.ofSeq
let asArrayMapped
(propertyName : SynExpr option)
(elementType : SynType)
(collectionType : string)
(node : SynExpr)
(body : SynExpr)
@@ -106,9 +93,20 @@ module internal JsonParseGenerator =
| Some propertyName -> assertPropertyExists propertyName node
|> SynExpr.callMethod "AsArray"
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(SynExpr.createLambda "elt" (assertNotNull (Ident.create "elt") body))
body
|> JsonSerializeGenerator.assertNotNull
(Ident.create "elt")
(match propertyName with
| None ->
SynExpr.CreateConst
$"Expected element of array (element type %s{SynType.toHumanReadableString elementType}) to be non-null, but found a null element"
| Some propertyName ->
SynExpr.CreateConst
$"Expected element of array (element type %s{SynType.toHumanReadableString elementType}) to be non-null, but found a null element, at %%s"
|> SynExpr.applyFunction (SynExpr.createIdent "sprintf")
|> SynExpr.applyTo propertyName)
|> SynExpr.createLambda "elt"
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "Seq" ; "map" ])
)
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ collectionType ; "ofSeq" ])
@@ -117,14 +115,41 @@ module internal JsonParseGenerator =
/// fun kvp -> let key = {key(kvp)} in let value = {value(kvp)} in (key, value))
/// The inputs will be fed with appropriate SynExprs to apply them to the `kvp.Key` and `kvp.Value` args.
let dictionaryMapper (key : SynExpr -> SynExpr) (value : SynExpr -> SynExpr) : SynExpr =
let dictionaryMapper
(propertyName : SynExpr option)
(valueTypeIsNullable : bool)
(key : SynExpr -> SynExpr)
(valueType : SynType)
(value : SynExpr -> SynExpr)
: SynExpr
=
let keyArg = SynExpr.createLongIdent [ "kvp" ; "Key" ] |> SynExpr.paren
let valueArg = SynExpr.createLongIdent [ "kvp" ; "Value" ] |> SynExpr.paren
let valueArg = SynExpr.createLongIdent [ "kvp" ; "Value" ]
let value =
if valueTypeIsNullable then
(value (SynExpr.createIdent "value"))
else
let errorMessage =
match propertyName with
| None ->
SynExpr.CreateConst
$"Expected dictionary value of type %s{SynType.toHumanReadableString valueType} to be non-null, but it was null"
| Some propertyName ->
SynExpr.CreateConst
$"Expected dictionary value of type %s{SynType.toHumanReadableString valueType} to be non-null, but it was null, at key %%s"
|> SynExpr.applyFunction (SynExpr.createIdent "sprintf")
|> SynExpr.applyTo propertyName
JsonSerializeGenerator.assertNotNull
(Ident.create "value")
errorMessage
(value (SynExpr.createIdent "value"))
// No need to paren here, we're on the LHS of a `let`
SynExpr.tupleNoParen [ SynExpr.createIdent "key" ; SynExpr.createIdent "value" ]
|> SynExpr.createLet [ SynBinding.basic [ Ident.create "value" ] [] (value valueArg) ]
SynExpr.tupleNoParen [ SynExpr.createIdent "key" ; value ]
|> SynExpr.createLet [ SynBinding.basic [ Ident.create "value" ] [] valueArg ]
|> SynExpr.createLet [ SynBinding.basic [ Ident.create "key" ] [] (key keyArg) ]
|> SynExpr.createLambda "kvp"
@@ -181,10 +206,61 @@ module internal JsonParseGenerator =
))
handler
let rec parseNullableNode
// TODO: unused?!
(propertyName : SynExpr option)
(options : JsonParseOption)
(fieldType : SynType)
(node : SynExpr)
: SynExpr
=
match fieldType with
| OptionType ty ->
match ty with
| OptionType _
| NullableType _ ->
failwith
$"Nested nullable types are not supported, because we can't distinguish between None and Some None. %s{SynType.toHumanReadableString ty}"
| _ ->
let someClause =
parseNonNullableNode None options ty (SynExpr.createIdent "v")
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "Some")
|> SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "v" ])
[
SynMatchClause.create (SynPat.named "None") (SynExpr.createIdent "None")
someClause
]
|> SynExpr.createMatch node
| NullableType ty ->
match ty with
| OptionType _
| NullableType _ ->
failwith
$"Nested nullable types are not supported, because we can't distinguish between None and Some None. %s{SynType.toHumanReadableString ty}"
| _ ->
let someClause =
parseNonNullableNode None options ty (SynExpr.createIdent "v")
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Nullable" ])
|> SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "v" ])
[
SynMatchClause.create
(SynPat.named "None")
(SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "Nullable" ]) (SynExpr.CreateConst ()))
someClause
]
|> SynExpr.createMatch node
| _ ->
failwith
$"Encountered type %s{SynType.toHumanReadableString fieldType} which is expected to be nullable, but couldn't identify it"
/// Given `node.["town"]`, for example, choose how to obtain a JSON value from it.
/// The property name is used in error messages at runtime to show where a JSON
/// parse error occurred; supply `None` to indicate "don't validate".
let rec parseNode
and parseNonNullableNode
(propertyName : SynExpr option)
(options : JsonParseOption)
(fieldType : SynType)
@@ -193,6 +269,10 @@ module internal JsonParseGenerator =
=
// TODO: parsing format for DateTime etc
match fieldType with
| OptionType _
| NullableType _ ->
failwith
$"Unexpectedly parsing nullable type %s{SynType.toHumanReadableString fieldType} as if it were non-nullable."
// Struct types
| DateOnly ->
node
@@ -217,79 +297,156 @@ module internal JsonParseGenerator =
|> asValueGetValue propertyName "string"
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "DateTimeOffset" ; "Parse" ])
| PrimitiveType typeName -> asValueGetValueIdent propertyName typeName node
| OptionType ty ->
let someClause =
parseNode None options ty (SynExpr.createIdent "v")
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "Some")
|> SynMatchClause.create (SynPat.named "v")
[
SynMatchClause.create SynPat.createNull (SynExpr.createIdent "None")
someClause
]
|> SynExpr.createMatch node
| NullableType ty ->
let someClause =
parseNode None options ty (SynExpr.createIdent "v")
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Nullable" ])
|> SynMatchClause.create (SynPat.named "v")
[
SynMatchClause.create
SynPat.createNull
(SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "Nullable" ]) (SynExpr.CreateConst ()))
someClause
]
|> SynExpr.createMatch node
| ListType ty ->
parseNode None options ty (SynExpr.createIdent "elt")
|> asArrayMapped propertyName "List" node
match JsonNodeWithNullability.Identify ty with
| CannotBeNull ->
parseNonNullableNode None options ty (SynExpr.createIdent "elt")
|> asArrayMapped propertyName ty "List" node
| Nullable ->
parseNullableNode None options ty (SynExpr.createIdent "elt")
|> asArrayMapped propertyName ty "List" node
| ArrayType ty ->
parseNode None options ty (SynExpr.createIdent "elt")
|> asArrayMapped propertyName "Array" node
match JsonNodeWithNullability.Identify ty with
| CannotBeNull ->
parseNonNullableNode None options ty (SynExpr.createIdent "elt")
|> asArrayMapped propertyName ty "Array" node
| Nullable ->
parseNullableNode None options ty (SynExpr.createIdent "elt")
|> asArrayMapped propertyName ty "Array" node
| IDictionaryType (keyType, valueType) ->
node
|> asObject propertyName
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(dictionaryMapper (parseKeyString keyType) (parseNode None options valueType))
)
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "dict")
match JsonNodeWithNullability.Identify valueType with
| CannotBeNull ->
node
|> asObject propertyName
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(dictionaryMapper
propertyName
false
(parseKeyString keyType)
valueType
(parseNonNullableNode None options valueType))
)
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "dict")
| Nullable ->
node
|> asObject propertyName
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(dictionaryMapper
propertyName
true
(parseKeyString keyType)
valueType
(parseNullableNode None options valueType))
)
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "dict")
| DictionaryType (keyType, valueType) ->
node
|> asObject propertyName
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(dictionaryMapper (parseKeyString keyType) (parseNode None options valueType))
)
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "KeyValuePair" ])
)
|> SynExpr.pipeThroughFunction (
SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "Dictionary" ]
)
match JsonNodeWithNullability.Identify valueType with
| CannotBeNull ->
node
|> asObject propertyName
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(dictionaryMapper
propertyName
false
(parseKeyString keyType)
valueType
(parseNonNullableNode None options valueType))
)
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "KeyValuePair" ])
)
|> SynExpr.pipeThroughFunction (
SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "Dictionary" ]
)
| Nullable ->
node
|> asObject propertyName
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(dictionaryMapper
propertyName
true
(parseKeyString keyType)
valueType
(parseNullableNode None options valueType))
)
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "KeyValuePair" ])
)
|> SynExpr.pipeThroughFunction (
SynExpr.createLongIdent [ "System" ; "Collections" ; "Generic" ; "Dictionary" ]
)
| IReadOnlyDictionaryType (keyType, valueType) ->
node
|> asObject propertyName
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(dictionaryMapper (parseKeyString keyType) (parseNode None options valueType))
)
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "readOnlyDict")
match JsonNodeWithNullability.Identify valueType with
| CannotBeNull ->
node
|> asObject propertyName
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(dictionaryMapper
propertyName
false
(parseKeyString keyType)
valueType
(parseNonNullableNode None options valueType))
)
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "readOnlyDict")
| Nullable ->
node
|> asObject propertyName
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(dictionaryMapper
propertyName
true
(parseKeyString keyType)
valueType
(parseNullableNode None options valueType))
)
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "readOnlyDict")
| MapType (keyType, valueType) ->
node
|> asObject propertyName
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(dictionaryMapper (parseKeyString keyType) (parseNode None options valueType))
)
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Map" ; "ofSeq" ])
match JsonNodeWithNullability.Identify valueType with
| CannotBeNull ->
node
|> asObject propertyName
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(dictionaryMapper
propertyName
false
(parseKeyString keyType)
valueType
(parseNonNullableNode None options valueType))
)
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Map" ; "ofSeq" ])
| Nullable ->
node
|> asObject propertyName
|> SynExpr.pipeThroughFunction (
SynExpr.applyFunction
(SynExpr.createLongIdent [ "Seq" ; "map" ])
(dictionaryMapper
propertyName
true
(parseKeyString keyType)
valueType
(parseNullableNode None options valueType))
)
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Map" ; "ofSeq" ])
| BigInt ->
node
|> SynExpr.callMethod "ToJsonString"
@@ -300,7 +457,7 @@ module internal JsonParseGenerator =
|> SynExpr.pipeThroughFunction (Measure.getLanguagePrimitivesMeasure primType)
| JsonNode -> node
| UnitType -> SynExpr.CreateConst ()
| _ ->
| fieldType ->
// Let's just hope that we've also got our own type annotation!
let typeName =
match fieldType with
@@ -315,8 +472,39 @@ module internal JsonParseGenerator =
/// propertyName is probably a string literal, but it could be a [<Literal>] variable
/// The result of this function is the body of a let-binding (not including the LHS of that let-binding).
let createParseRhs (options : JsonParseOption) (propertyName : SynExpr) (fieldType : SynType) : SynExpr =
let objectToParse = SynExpr.createIdent "node" |> SynExpr.index propertyName
parseNode (Some propertyName) options fieldType objectToParse
match JsonNodeWithNullability.Identify fieldType with
| Nullable ->
let objectToParse =
SynExpr.createIdent "node"
|> SynExpr.index propertyName
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
parseNullableNode (Some propertyName) options fieldType objectToParse
| CannotBeNull ->
[
SynMatchClause.create
(SynPat.named "None")
(SynExpr.applyFunction
(SynExpr.createIdent "raise")
(SynExpr.paren (
SynExpr.applyFunction
(SynExpr.createLongIdent
[ "System" ; "Collections" ; "Generic" ; "KeyNotFoundException" ])
(SynExpr.applyFunction
(SynExpr.createIdent "sprintf")
(SynExpr.CreateConst "Required key '%s' not found on JSON object")
|> SynExpr.applyTo (SynExpr.paren propertyName)
|> SynExpr.paren)
)))
SynMatchClause.create
(SynPat.nameWithArgs "Some" [ SynPat.named "node" ])
(parseNonNullableNode None options fieldType (SynExpr.createIdent "node"))
]
|> SynExpr.createMatch (
SynExpr.createIdent "node"
|> SynExpr.index propertyName
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
)
let isJsonNumberHandling (literal : LongIdent) : bool =
match List.rev literal |> List.map (fun ident -> ident.idText) with
@@ -523,6 +711,7 @@ module internal JsonParseGenerator =
|> SynExpr.createLet
[
SynExpr.index (SynExpr.CreateConst "data") (SynExpr.createIdent "node")
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
|> assertPropertyExists (SynExpr.CreateConst "data")
|> SynBinding.basic [ Ident.create "node" ] []
]
@@ -571,6 +760,7 @@ module internal JsonParseGenerator =
SynExpr.createIdent "node"
|> SynExpr.index property
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "ofObj" ])
|> assertPropertyExists property
|> SynExpr.pipeThroughFunction (
SynExpr.createLambda "v" (SynExpr.callGenericMethod' "GetValue" "string" (SynExpr.createIdent "v"))

View File

@@ -10,24 +10,100 @@ type internal JsonSerializeOutputSpec =
ExtensionMethods : bool
}
/// https://github.com/Smaug123/WoofWare.Myriad/issues/364
/// The insane design of System.Text.Json is finally causing us to
/// do vast amounts of coding rather than merely being very annoying.
type internal JsonNodeWithNullability =
| CannotBeNull
| Nullable
static member Identify (ty : SynType) : JsonNodeWithNullability =
match ty with
| OptionType _
| NullableType _ -> JsonNodeWithNullability.Nullable
| _ -> JsonNodeWithNullability.CannotBeNull
[<RequireQualifiedAccess>]
module internal JsonSerializeGenerator =
open Fantomas.FCS.Text.Range
// The absolutely galaxy-brained implementation of JsonValue has `JsonValue.Parse "null"`
// identically equal to null. We have to work around this later, but we might as well just
// be efficient here and whip up the null directly.
let private jsonNull () =
SynExpr.createNull ()
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
// identically equal to null, so it's hard to use that type. We use `None` instead to represent
// the JSON null value.
let private jsonNull () = SynExpr.createIdent "None"
let assertNotNull (boundIdent : Ident) (message : SynExpr) (body : SynExpr) : SynExpr =
let raiseExpr =
message
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "ArgumentNullException" ])
|> SynExpr.paren
|> SynExpr.applyFunction (SynExpr.createIdent "raise")
[
SynMatchClause.create SynPat.createNull raiseExpr
SynMatchClause.create (SynPat.namedI boundIdent) body
]
|> SynExpr.createMatch (SynExpr.createIdent' boundIdent)
|> SynExpr.paren
/// The output of this will be an *optional* JsonNode.
let rec serializeNodeNullable (fieldType : SynType) : SynExpr * bool =
match fieldType with
| NullableType ty ->
// fun field -> if field.HasValue then {serializeNode ty} field.Value else JsonValue.Create null
match JsonNodeWithNullability.Identify ty with
| JsonNodeWithNullability.Nullable ->
failwith
$"We don't support nested nullable types, because we can't tell the difference between None and Some None: %s{SynType.toHumanReadableString ty}"
| JsonNodeWithNullability.CannotBeNull ->
let inner, innerIsJsonNode = serializeNodeNonNullable ty
SynExpr.applyFunction inner (SynExpr.createLongIdent [ "field" ; "Value" ])
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "Some")
|> SynExpr.ifThenElse (SynExpr.createLongIdent [ "field" ; "HasValue" ]) (jsonNull ())
|> SynExpr.createLambda "field"
|> fun e -> e, innerIsJsonNode
| OptionType ty ->
// fun field -> match field with | None -> None | Some v -> {serializeNode ty} field |> Some
match JsonNodeWithNullability.Identify ty with
| JsonNodeWithNullability.Nullable ->
failwith
$"We don't support nested nullable types, because we can't tell the difference between None and Some None: %s{SynType.toHumanReadableString ty}"
| JsonNodeWithNullability.CannotBeNull ->
let noneClause = jsonNull () |> SynMatchClause.create (SynPat.named "None")
let someClause =
let inner, innerIsJsonNode = serializeNodeNonNullable ty
let target = SynExpr.pipeThroughFunction inner (SynExpr.createIdent "field")
if innerIsJsonNode then
target
else
target
|> SynExpr.paren
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "Some")
|> SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "field" ])
[ noneClause ; someClause ]
|> SynExpr.createMatch (SynExpr.createIdent "field")
|> SynExpr.createLambda "field"
|> fun e -> e, true
| _ -> failwith $"Did not recognise type %s{SynType.toHumanReadableString fieldType} as nullable"
/// Given `input.Ident`, for example, choose how to add it to the ambient `node`.
/// The result is a line like `(fun ident -> InnerType.toJsonNode ident)` or `(fun ident -> JsonValue.Create ident)`.
/// Returns also a bool which is true if the resulting SynExpr represents something of type JsonNode.
let rec serializeNode (fieldType : SynType) : SynExpr * bool =
and serializeNodeNonNullable (fieldType : SynType) : SynExpr * bool =
// TODO: serialization format for DateTime etc
match fieldType with
| OptionType _
| NullableType _ ->
failwith $"Tried to treat the type %s{SynType.toHumanReadableString fieldType} as non-nullable"
| DateOnly
| DateTime
| NumberType _
@@ -36,8 +112,21 @@ module internal JsonSerializeGenerator =
| Guid
| Uri ->
// JsonValue.Create<type>
SynExpr.createLongIdent [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonValue" ; "Create" ]
|> SynExpr.typeApp [ fieldType ]
(SynExpr.createIdent "field")
|> assertNotNull
(Ident.create "field")
(SynExpr.CreateConst
$"Expected type %s{SynType.toHumanReadableString fieldType} to be non-null, but received a null value when serialising")
|> SynExpr.createLet
[
SynBinding.basic
[ Ident.create "field" ]
[]
(SynExpr.createLongIdent [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonValue" ; "Create" ]
|> SynExpr.typeApp [ fieldType ]
|> SynExpr.applyTo (SynExpr.createIdent "field"))
]
|> SynExpr.createLambda "field"
|> fun e -> e, false
| DateTimeOffset ->
// fun field -> field.ToString("o") |> JsonValue.Create<string>
@@ -50,41 +139,17 @@ module internal JsonSerializeGenerator =
|> SynExpr.pipeThroughFunction create
|> SynExpr.createLambda "field"
|> fun e -> e, false
| NullableType ty ->
// fun field -> if field.HasValue then {serializeNode ty} field.Value else JsonValue.Create null
let inner, innerIsJsonNode = serializeNode ty
SynExpr.applyFunction inner (SynExpr.createLongIdent [ "field" ; "Value" ])
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|> SynExpr.ifThenElse (SynExpr.createLongIdent [ "field" ; "HasValue" ]) (jsonNull ())
|> SynExpr.createLambda "field"
|> fun e -> e, innerIsJsonNode
| OptionType ty ->
// fun field -> match field with | None -> JsonValue.Create null | Some v -> {serializeNode ty} field
let noneClause = jsonNull () |> SynMatchClause.create (SynPat.named "None")
let someClause =
let inner, innerIsJsonNode = serializeNode ty
let target = SynExpr.applyFunction inner (SynExpr.createIdent "field")
if innerIsJsonNode then
target
else
target
|> SynExpr.paren
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|> SynMatchClause.create (SynPat.nameWithArgs "Some" [ SynPat.named "field" ])
[ noneClause ; someClause ]
|> SynExpr.createMatch (SynExpr.createIdent "field")
|> SynExpr.createLambda "field"
|> fun e -> e, true
| ArrayType ty
| ListType ty ->
// fun field ->
// let arr = JsonArray ()
// for mem in field do arr.Add ({serializeNode} mem)
// arr
let isNullableChild =
match JsonNodeWithNullability.Identify ty with
| CannotBeNull -> false
| Nullable -> true
[
SynExpr.ForEach (
DebugPointAtFor.Yes range0,
@@ -95,7 +160,17 @@ module internal JsonSerializeGenerator =
SynExpr.createIdent "field",
SynExpr.applyFunction
(SynExpr.createLongIdent [ "arr" ; "Add" ])
(SynExpr.paren (SynExpr.applyFunction (fst (serializeNode ty)) (SynExpr.createIdent "mem"))),
(SynExpr.paren (
SynExpr.applyFunction
(fst (
(if isNullableChild then
serializeNodeNullable
else
serializeNodeNonNullable)
ty
))
(SynExpr.createIdent "mem")
)),
range0
)
SynExpr.createIdent "arr"
@@ -109,15 +184,28 @@ module internal JsonSerializeGenerator =
]
|> SynExpr.createLambda "field"
|> fun e -> e, false
| IDictionaryType (_keyType, valueType)
| DictionaryType (_keyType, valueType)
| IReadOnlyDictionaryType (_keyType, valueType)
| MapType (_keyType, valueType) ->
| IDictionaryType (keyType, valueType)
| DictionaryType (keyType, valueType)
| IReadOnlyDictionaryType (keyType, valueType)
| MapType (keyType, valueType) ->
// fun field ->
// let ret = JsonObject ()
// for (KeyValue(key, value)) in field do
// ret.Add (key.ToString (), {serializeNode} value)
// ret
let isNullableValueField =
match JsonNodeWithNullability.Identify valueType with
| CannotBeNull -> false
| Nullable -> true
// TODO: this is a bit dubious, because user-defined types will
// by default have non-null ToString
let keyTypeHasNonNullToString =
match keyType with
| String
| Uri -> true
| _ -> false
[
SynExpr.ForEach (
DebugPointAtFor.Yes range0,
@@ -130,10 +218,33 @@ module internal JsonSerializeGenerator =
(SynExpr.createLongIdent [ "ret" ; "Add" ])
(SynExpr.tuple
[
SynExpr.createLongIdent [ "key" ; "ToString" ]
|> SynExpr.applyTo (SynExpr.CreateConst ())
SynExpr.applyFunction (fst (serializeNode valueType)) (SynExpr.createIdent "value")
]),
SynExpr.createIdent "key"
|> if keyTypeHasNonNullToString then
id
else
assertNotNull
(Ident.create "key")
(SynExpr.CreateConst
"A map key unexpectedly yielded null when we `ToString`'ed it. Map keys must yield non-null strings on `ToString`.")
SynExpr.applyFunction
(fst (
(if isNullableValueField then
serializeNodeNullable
else
serializeNodeNonNullable)
valueType
))
(SynExpr.createIdent "value")
])
|> SynExpr.createLet
[
SynBinding.basic
[ Ident.create "key" ]
[]
(SynExpr.createLongIdent [ "key" ; "ToString" ]
|> SynExpr.applyTo (SynExpr.CreateConst ()))
],
range0
)
SynExpr.createIdent "ret"
@@ -166,13 +277,24 @@ module internal JsonSerializeGenerator =
/// propertyName is probably a string literal, but it could be a [<Literal>] variable
/// `node.Add ({propertyName}, {toJsonNode})`
let createSerializeRhsRecord (propertyName : SynExpr) (fieldId : Ident) (fieldType : SynType) : SynExpr =
[
propertyName
SynExpr.pipeThroughFunction
(fst (serializeNode fieldType))
(SynExpr.createLongIdent' [ Ident.create "input" ; fieldId ])
|> SynExpr.paren
]
let isNullableField =
match JsonNodeWithNullability.Identify fieldType with
| CannotBeNull -> false
| Nullable -> true
let serialised =
if isNullableField then
let value =
serializeNodeNullable fieldType
|> fst
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "Option" ; "toObj" ])
SynExpr.pipeThroughFunction value (SynExpr.createLongIdent' [ Ident.create "input" ; fieldId ])
else
let value = serializeNodeNonNullable fieldType |> fst
SynExpr.pipeThroughFunction value (SynExpr.createLongIdent' [ Ident.create "input" ; fieldId ])
[ propertyName ; SynExpr.paren serialised ]
|> SynExpr.tuple
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "node" ; "Add" ])
@@ -278,7 +400,10 @@ module internal JsonSerializeGenerator =
| DictionaryType (String, v) -> v
| _ -> failwith "Expected JsonExtensionData to be a Dictionary<string, something>"
let serialise = fst (serializeNode valType)
let serialise =
match JsonNodeWithNullability.Identify valType with
| CannotBeNull -> fst (serializeNodeNonNullable valType)
| Nullable -> fst (serializeNodeNullable valType)
SynExpr.createIdent "node"
|> SynExpr.callMethodArg
@@ -343,7 +468,15 @@ module internal JsonSerializeGenerator =
let propertyName = getPropertyName (Option.get fieldData.Ident) fieldData.Attrs
let node =
SynExpr.applyFunction (fst (serializeNode fieldData.Type)) (SynExpr.createIdent caseName)
match JsonNodeWithNullability.Identify fieldData.Type with
| CannotBeNull ->
SynExpr.applyFunction
(fst (serializeNodeNonNullable fieldData.Type))
(SynExpr.createIdent caseName)
| Nullable ->
SynExpr.applyFunction
(fst (serializeNodeNullable fieldData.Type))
(SynExpr.createIdent caseName)
[ propertyName ; node ]
|> SynExpr.tuple

View File

@@ -22,7 +22,7 @@
<ItemGroup>
<PackageReference Include="Myriad.Core" Version="0.8.3" />
<PackageReference Include="TypeEquality" Version="0.3.0" />
<PackageReference Include="WoofWare.Whippet.Fantomas" Version="0.6.1" />
<PackageReference Include="WoofWare.Whippet.Fantomas" Version="0.6.2" />
<!-- the lowest version allowed by Myriad.Core -->
<PackageReference Update="FSharp.Core" Version="6.0.1" PrivateAssets="all"/>
</ItemGroup>

View File

@@ -1,5 +1,5 @@
{
"version": "6.0",
"version": "7.0",
"publicReleaseRefSpec": [
"^refs/heads/main$"
],

View File

@@ -381,7 +381,7 @@
},
{
"pname": "WoofWare.Whippet.Fantomas",
"version": "0.6.1",
"hash": "sha256-UTK+WbHR83zbMZ+2BzecIrKvp/5ZppHToIZ/oHTIF1k="
"version": "0.6.2",
"hash": "sha256-nDT/W5eBwM/E+Z2oQ80maAGYrEyRJQXL1unxR9q6ztU="
}
]