Print out missing field names (#29)

This commit is contained in:
Patrick Stevens
2023-12-29 11:54:53 +00:00
committed by GitHub
parent d4212ca887
commit 44bf3eed24
5 changed files with 784 additions and 81 deletions

View File

@@ -11,7 +11,17 @@ namespace ConsumePlugin
module InnerType = module InnerType =
/// Parse from a JSON node. /// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : InnerType = let jsonParse (node : System.Text.Json.Nodes.JsonNode) : InnerType =
let Thing = node.[(Literals.something)].AsValue().GetValue<string> () let Thing =
(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<string> ()
{ {
Thing = Thing Thing = Thing
@@ -25,24 +35,69 @@ module JsonRecordType =
/// Parse from a JSON node. /// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : JsonRecordType = let jsonParse (node : System.Text.Json.Nodes.JsonNode) : JsonRecordType =
let F = let F =
node.["f"].AsArray () (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 -> elt.AsValue().GetValue<int> ()) |> Seq.map (fun elt -> elt.AsValue().GetValue<int> ())
|> Array.ofSeq |> Array.ofSeq
let E = let E =
node.["e"].AsArray () (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 -> elt.AsValue().GetValue<string> ()) |> Seq.map (fun elt -> elt.AsValue().GetValue<string> ())
|> Array.ofSeq |> Array.ofSeq
let D = InnerType.jsonParse node.["d"] let D = InnerType.jsonParse node.["d"]
let C = let C =
node.["hi"].AsArray () (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 -> elt.AsValue().GetValue<int> ()) |> Seq.map (fun elt -> elt.AsValue().GetValue<int> ())
|> List.ofSeq |> List.ofSeq
let B = node.["another-thing"].AsValue().GetValue<string> () let B =
let A = node.["a"].AsValue().GetValue<int> () (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<string> ()
let A =
(match node.["a"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("a")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
{ {
A = A A = A

View File

@@ -12,11 +12,29 @@ module GymOpeningHours =
/// Parse from a JSON node. /// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : GymOpeningHours = let jsonParse (node : System.Text.Json.Nodes.JsonNode) : GymOpeningHours =
let OpeningHours = let OpeningHours =
node.["openingHours"].AsArray () (match node.["openingHours"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("openingHours")
)
)
| v -> v)
.AsArray ()
|> Seq.map (fun elt -> elt.AsValue().GetValue<string> ()) |> Seq.map (fun elt -> elt.AsValue().GetValue<string> ())
|> List.ofSeq |> List.ofSeq
let IsAlwaysOpen = node.["isAlwaysOpen"].AsValue().GetValue<bool> () let IsAlwaysOpen =
(match node.["isAlwaysOpen"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("isAlwaysOpen")
)
)
| v -> v)
.AsValue()
.GetValue<bool> ()
{ {
IsAlwaysOpen = IsAlwaysOpen IsAlwaysOpen = IsAlwaysOpen
@@ -30,8 +48,29 @@ namespace PureGym
module GymAccessOptions = module GymAccessOptions =
/// Parse from a JSON node. /// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : GymAccessOptions = let jsonParse (node : System.Text.Json.Nodes.JsonNode) : GymAccessOptions =
let QrCodeAccess = node.["qrCodeAccess"].AsValue().GetValue<bool> () let QrCodeAccess =
let PinAccess = node.["pinAccess"].AsValue().GetValue<bool> () (match node.["qrCodeAccess"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("qrCodeAccess")
)
)
| v -> v)
.AsValue()
.GetValue<bool> ()
let PinAccess =
(match node.["pinAccess"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("pinAccess")
)
)
| v -> v)
.AsValue()
.GetValue<bool> ()
{ {
PinAccess = PinAccess PinAccess = PinAccess
@@ -47,13 +86,32 @@ module GymLocation =
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : GymLocation = let jsonParse (node : System.Text.Json.Nodes.JsonNode) : GymLocation =
let Latitude = let Latitude =
try try
node.["latitude"].AsValue().GetValue<float> () (match node.["latitude"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("latitude")
)
)
| v -> v)
.AsValue()
.GetValue<float> ()
with :? System.InvalidOperationException as exc -> with :? System.InvalidOperationException as exc ->
if exc.Message.Contains "cannot be converted to" then if exc.Message.Contains "cannot be converted to" then
if if
System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString = System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString = System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString
then then
node.["latitude"].AsValue().GetValue<string> () |> System.Double.Parse (match node.["latitude"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("latitude")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
|> System.Double.Parse
else else
reraise () reraise ()
else else
@@ -61,13 +119,32 @@ module GymLocation =
let Longitude = let Longitude =
try try
node.["longitude"].AsValue().GetValue<float> () (match node.["longitude"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("longitude")
)
)
| v -> v)
.AsValue()
.GetValue<float> ()
with :? System.InvalidOperationException as exc -> with :? System.InvalidOperationException as exc ->
if exc.Message.Contains "cannot be converted to" then if exc.Message.Contains "cannot be converted to" then
if if
System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString = System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString = System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString
then then
node.["longitude"].AsValue().GetValue<string> () |> System.Double.Parse (match node.["longitude"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("longitude")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
|> System.Double.Parse
else else
reraise () reraise ()
else else
@@ -85,14 +162,34 @@ namespace PureGym
module GymAddress = module GymAddress =
/// Parse from a JSON node. /// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : GymAddress = let jsonParse (node : System.Text.Json.Nodes.JsonNode) : GymAddress =
let Postcode = node.["postcode"].AsValue().GetValue<string> () let Postcode =
(match node.["postcode"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("postcode")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let County = let County =
match node.["county"] with match node.["county"] with
| null -> None | null -> None
| v -> v.AsValue().GetValue<string> () |> Some | v -> v.AsValue().GetValue<string> () |> Some
let Town = node.["town"].AsValue().GetValue<string> () let Town =
(match node.["town"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("town")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let AddressLine3 = let AddressLine3 =
match node.["addressLine3"] with match node.["addressLine3"] with
@@ -104,7 +201,17 @@ module GymAddress =
| null -> None | null -> None
| v -> v.AsValue().GetValue<string> () |> Some | v -> v.AsValue().GetValue<string> () |> Some
let AddressLine1 = node.["addressLine1"].AsValue().GetValue<string> () let AddressLine1 =
(match node.["addressLine1"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("addressLine1")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
{ {
AddressLine1 = AddressLine1 AddressLine1 = AddressLine1
@@ -122,17 +229,95 @@ namespace PureGym
module Gym = module Gym =
/// Parse from a JSON node. /// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : Gym = let jsonParse (node : System.Text.Json.Nodes.JsonNode) : Gym =
let ReopenDate = node.["reopenDate"].AsValue().GetValue<string> () let ReopenDate =
let TimeZone = node.["timeZone"].AsValue().GetValue<string> () (match node.["reopenDate"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("reopenDate")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let TimeZone =
(match node.["timeZone"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("timeZone")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let Location = GymLocation.jsonParse node.["location"] let Location = GymLocation.jsonParse node.["location"]
let AccessOptions = GymAccessOptions.jsonParse node.["accessOptions"] let AccessOptions = GymAccessOptions.jsonParse node.["accessOptions"]
let GymOpeningHours = GymOpeningHours.jsonParse node.["gymOpeningHours"] let GymOpeningHours = GymOpeningHours.jsonParse node.["gymOpeningHours"]
let EmailAddress = node.["emailAddress"].AsValue().GetValue<string> ()
let PhoneNumber = node.["phoneNumber"].AsValue().GetValue<string> () let EmailAddress =
(match node.["emailAddress"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("emailAddress")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let PhoneNumber =
(match node.["phoneNumber"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("phoneNumber")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let Address = GymAddress.jsonParse node.["address"] let Address = GymAddress.jsonParse node.["address"]
let Status = node.["status"].AsValue().GetValue<int> ()
let Id = node.["id"].AsValue().GetValue<int> () let Status =
let Name = node.["name"].AsValue().GetValue<string> () (match node.["status"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("status")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let Id =
(match node.["id"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("id")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let Name =
(match node.["name"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("name")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
{ {
Name = Name Name = Name
@@ -155,24 +340,186 @@ namespace PureGym
module Member = module Member =
/// Parse from a JSON node. /// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : Member = let jsonParse (node : System.Text.Json.Nodes.JsonNode) : Member =
let MemberStatus = node.["memberStatus"].AsValue().GetValue<int> () let MemberStatus =
let SuspendedReason = node.["suspendedReason"].AsValue().GetValue<int> () (match node.["memberStatus"] with
let MembershipLevel = node.["membershipLevel"].AsValue().GetValue<int> () | null ->
let MembershipName = node.["membershipName"].AsValue().GetValue<string> () raise (
let Postcode = node.["postCode"].AsValue().GetValue<string> () System.Collections.Generic.KeyNotFoundException (
let MobileNumber = node.["mobileNumber"].AsValue().GetValue<string> () sprintf "Required key '%s' not found on JSON object" ("memberStatus")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let SuspendedReason =
(match node.["suspendedReason"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("suspendedReason")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let MembershipLevel =
(match node.["membershipLevel"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("membershipLevel")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let MembershipName =
(match node.["membershipName"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("membershipName")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let Postcode =
(match node.["postCode"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("postCode")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let MobileNumber =
(match node.["mobileNumber"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("mobileNumber")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let DateOfBirth = let DateOfBirth =
node.["dateofBirth"].AsValue().GetValue<string> () |> System.DateOnly.Parse (match node.["dateofBirth"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("dateofBirth")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
|> System.DateOnly.Parse
let GymAccessPin = node.["gymAccessPin"].AsValue().GetValue<string> () let GymAccessPin =
let EmailAddress = node.["emailAddress"].AsValue().GetValue<string> () (match node.["gymAccessPin"] with
let HomeGymName = node.["homeGymName"].AsValue().GetValue<string> () | null ->
let HomeGymId = node.["homeGymId"].AsValue().GetValue<int> () raise (
let LastName = node.["lastName"].AsValue().GetValue<string> () System.Collections.Generic.KeyNotFoundException (
let FirstName = node.["firstName"].AsValue().GetValue<string> () sprintf "Required key '%s' not found on JSON object" ("gymAccessPin")
let CompoundMemberId = node.["compoundMemberId"].AsValue().GetValue<string> () )
let Id = node.["id"].AsValue().GetValue<int> () )
| v -> v)
.AsValue()
.GetValue<string> ()
let EmailAddress =
(match node.["emailAddress"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("emailAddress")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let HomeGymName =
(match node.["homeGymName"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("homeGymName")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let HomeGymId =
(match node.["homeGymId"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("homeGymId")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let LastName =
(match node.["lastName"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lastName")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let FirstName =
(match node.["firstName"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("firstName")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let CompoundMemberId =
(match node.["compoundMemberId"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("compoundMemberId")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let Id =
(match node.["id"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("id")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
{ {
Id = Id Id = Id
@@ -199,28 +546,109 @@ namespace PureGym
module GymAttendance = module GymAttendance =
/// Parse from a JSON node. /// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : GymAttendance = let jsonParse (node : System.Text.Json.Nodes.JsonNode) : GymAttendance =
let MaximumCapacity = node.["maximumCapacity"].AsValue().GetValue<int> () let MaximumCapacity =
(match node.["maximumCapacity"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("maximumCapacity")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let LastRefreshedPeopleInClasses = let LastRefreshedPeopleInClasses =
node.["lastRefreshedPeopleInClasses"].AsValue().GetValue<string> () (match node.["lastRefreshedPeopleInClasses"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lastRefreshedPeopleInClasses")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
|> System.DateTime.Parse |> System.DateTime.Parse
let LastRefreshed = let LastRefreshed =
node.["lastRefreshed"].AsValue().GetValue<string> () |> System.DateTime.Parse (match node.["lastRefreshed"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lastRefreshed")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
|> System.DateTime.Parse
let AttendanceTime = let AttendanceTime =
node.["attendanceTime"].AsValue().GetValue<string> () |> System.DateTime.Parse (match node.["attendanceTime"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("attendanceTime")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
|> System.DateTime.Parse
let IsApproximate = node.["isApproximate"].AsValue().GetValue<bool> () let IsApproximate =
(match node.["isApproximate"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("isApproximate")
)
)
| v -> v)
.AsValue()
.GetValue<bool> ()
let TotalPeopleSuffix = let TotalPeopleSuffix =
match node.["totalPeopleSuffix"] with match node.["totalPeopleSuffix"] with
| null -> None | null -> None
| v -> v.AsValue().GetValue<string> () |> Some | v -> v.AsValue().GetValue<string> () |> Some
let TotalPeopleInClasses = node.["totalPeopleInClasses"].AsValue().GetValue<int> () let TotalPeopleInClasses =
let TotalPeopleInGym = node.["totalPeopleInGym"].AsValue().GetValue<int> () (match node.["totalPeopleInClasses"] with
let Description = node.["description"].AsValue().GetValue<string> () | null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("totalPeopleInClasses")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let TotalPeopleInGym =
(match node.["totalPeopleInGym"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("totalPeopleInGym")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let Description =
(match node.["description"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("description")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
{ {
Description = Description Description = Description
@@ -242,13 +670,77 @@ module MemberActivityDto =
/// Parse from a JSON node. /// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : MemberActivityDto = let jsonParse (node : System.Text.Json.Nodes.JsonNode) : MemberActivityDto =
let LastRefreshed = let LastRefreshed =
node.["lastRefreshed"].AsValue().GetValue<string> () |> System.DateTime.Parse (match node.["lastRefreshed"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("lastRefreshed")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
|> System.DateTime.Parse
let IsEstimated = node.["isEstimated"].AsValue().GetValue<bool> () let IsEstimated =
let TotalClasses = node.["totalClasses"].AsValue().GetValue<int> () (match node.["isEstimated"] with
let TotalVisits = node.["totalVisits"].AsValue().GetValue<int> () | null ->
let AverageDuration = node.["averageDuration"].AsValue().GetValue<int> () raise (
let TotalDuration = node.["totalDuration"].AsValue().GetValue<int> () System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("isEstimated")
)
)
| v -> v)
.AsValue()
.GetValue<bool> ()
let TotalClasses =
(match node.["totalClasses"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("totalClasses")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let TotalVisits =
(match node.["totalVisits"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("totalVisits")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let AverageDuration =
(match node.["averageDuration"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("averageDuration")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let TotalDuration =
(match node.["totalDuration"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("totalDuration")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
{ {
TotalDuration = TotalDuration TotalDuration = TotalDuration
@@ -266,9 +758,41 @@ namespace PureGym
module SessionsAggregate = module SessionsAggregate =
/// Parse from a JSON node. /// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : SessionsAggregate = let jsonParse (node : System.Text.Json.Nodes.JsonNode) : SessionsAggregate =
let Duration = node.["Duration"].AsValue().GetValue<int> () let Duration =
let Visits = node.["Visits"].AsValue().GetValue<int> () (match node.["Duration"] with
let Activities = node.["Activities"].AsValue().GetValue<int> () | null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("Duration")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let Visits =
(match node.["Visits"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("Visits")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let Activities =
(match node.["Activities"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("Activities")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
{ {
Activities = Activities Activities = Activities
@@ -283,9 +807,41 @@ namespace PureGym
module VisitGym = module VisitGym =
/// Parse from a JSON node. /// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : VisitGym = let jsonParse (node : System.Text.Json.Nodes.JsonNode) : VisitGym =
let Status = node.["Status"].AsValue().GetValue<string> () let Status =
let Name = node.["Name"].AsValue().GetValue<string> () (match node.["Status"] with
let Id = node.["Id"].AsValue().GetValue<int> () | null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("Status")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let Name =
(match node.["Name"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("Name")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
let Id =
(match node.["Id"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("Id")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
{ {
Id = Id Id = Id
@@ -301,12 +857,43 @@ module Visit =
/// Parse from a JSON node. /// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : Visit = let jsonParse (node : System.Text.Json.Nodes.JsonNode) : Visit =
let Gym = VisitGym.jsonParse node.["Gym"] let Gym = VisitGym.jsonParse node.["Gym"]
let Duration = node.["Duration"].AsValue().GetValue<int> ()
let Duration =
(match node.["Duration"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("Duration")
)
)
| v -> v)
.AsValue()
.GetValue<int> ()
let StartTime = let StartTime =
node.["StartTime"].AsValue().GetValue<string> () |> System.DateTime.Parse (match node.["StartTime"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("StartTime")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
|> System.DateTime.Parse
let IsDurationEstimated = node.["IsDurationEstimated"].AsValue().GetValue<bool> () let IsDurationEstimated =
(match node.["IsDurationEstimated"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("IsDurationEstimated")
)
)
| v -> v)
.AsValue()
.GetValue<bool> ()
{ {
IsDurationEstimated = IsDurationEstimated IsDurationEstimated = IsDurationEstimated
@@ -338,7 +925,15 @@ module Sessions =
/// Parse from a JSON node. /// Parse from a JSON node.
let jsonParse (node : System.Text.Json.Nodes.JsonNode) : Sessions = let jsonParse (node : System.Text.Json.Nodes.JsonNode) : Sessions =
let Visits = let Visits =
node.["Visits"].AsArray () (match node.["Visits"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("Visits")
)
)
| v -> v)
.AsArray ()
|> Seq.map (fun elt -> Visit.jsonParse elt) |> Seq.map (fun elt -> Visit.jsonParse elt)
|> List.ofSeq |> List.ofSeq

View File

@@ -87,7 +87,6 @@ However, there is *far* more that could be done.
* Make it possible to give an exact format and cultural info in date and time parsing. * Make it possible to give an exact format and cultural info in date and time parsing.
* Make it possible to reject parsing if extra fields are present. * Make it possible to reject parsing if extra fields are present.
* Rather than just throwing `NullReferenceException`, print out the field name that failed.
* Generally support all the `System.Text.Json` attributes. * Generally support all the `System.Text.Json` attributes.
## `RemoveOptions` ## `RemoveOptions`

View File

@@ -326,6 +326,7 @@ module internal HttpClientGenerator =
let returnExpr = let returnExpr =
JsonParseGenerator.parseNode JsonParseGenerator.parseNode
None
JsonParseGenerator.JsonParseOption.None JsonParseGenerator.JsonParseOption.None
info.ReturnType info.ReturnType
(SynExpr.CreateIdentString "node") (SynExpr.CreateIdentString "node")

View File

@@ -27,9 +27,44 @@ module internal JsonParseGenerator =
JsonNumberHandlingArg = None JsonNumberHandlingArg = None
} }
/// (match {indexed} with | null -> raise (System.Collections.Generic.KeyNotFoundException ()) | v -> v)
let assertNotNull (propertyName : SynExpr) (indexed : SynExpr) =
let raiseExpr =
SynExpr.CreateApp (
SynExpr.CreateIdentString "raise",
SynExpr.CreateParen (
SynExpr.CreateApp (
SynExpr.CreateLongIdent (
SynLongIdent.Create [ "System" ; "Collections" ; "Generic" ; "KeyNotFoundException" ]
),
SynExpr.CreateParen (
SynExpr.CreateApp (
SynExpr.CreateApp (
SynExpr.CreateIdentString "sprintf",
SynExpr.CreateConstString "Required key '%s' not found on JSON object"
),
SynExpr.CreateParen propertyName
)
)
)
)
)
SynExpr.CreateMatch (
indexed,
[
SynMatchClause.Create (SynPat.CreateNull, None, raiseExpr)
SynMatchClause.Create (SynPat.CreateNamed (Ident.Create "v"), None, SynExpr.CreateIdentString "v")
]
)
|> SynExpr.CreateParen
/// {node}.AsValue().GetValue<{typeName}> () /// {node}.AsValue().GetValue<{typeName}> ()
let asValueGetValue (typeName : string) (node : SynExpr) : SynExpr = /// If `propertyName` is Some, uses `assertNotNull {node}` instead of `{node}`.
node let asValueGetValue (propertyName : SynExpr option) (typeName : string) (node : SynExpr) : SynExpr =
match propertyName with
| None -> node
| Some propertyName -> assertNotNull propertyName node
|> SynExpr.callMethod "AsValue" |> SynExpr.callMethod "AsValue"
|> SynExpr.callGenericMethod "GetValue" typeName |> SynExpr.callGenericMethod "GetValue" typeName
@@ -42,11 +77,19 @@ module internal JsonParseGenerator =
/// collectionType is e.g. "List"; we'll be calling `ofSeq` on it. /// collectionType is e.g. "List"; we'll be calling `ofSeq` on it.
/// body is the body of a lambda which takes a parameter `elt`. /// body is the body of a lambda which takes a parameter `elt`.
/// {node}.AsArray() /// {assertNotNull node}.AsArray()
/// |> Seq.map (fun elt -> {body}) /// |> Seq.map (fun elt -> {body})
/// |> {collectionType}.ofSeq /// |> {collectionType}.ofSeq
let asArrayMapped (collectionType : string) (node : SynExpr) (body : SynExpr) : SynExpr = let asArrayMapped
node (propertyName : SynExpr option)
(collectionType : string)
(node : SynExpr)
(body : SynExpr)
: SynExpr
=
match propertyName with
| None -> node
| Some propertyName -> assertNotNull propertyName node
|> SynExpr.callMethod "AsArray" |> SynExpr.callMethod "AsArray"
|> SynExpr.pipeThroughFunction ( |> SynExpr.pipeThroughFunction (
SynExpr.CreateApp ( SynExpr.CreateApp (
@@ -74,21 +117,31 @@ module internal JsonParseGenerator =
List.append (SynExpr.qualifyPrimitiveType typeName) [ Ident.Create "Parse" ] List.append (SynExpr.qualifyPrimitiveType typeName) [ Ident.Create "Parse" ]
/// Given `node.["town"]`, for example, choose how to obtain a JSON value from it. /// Given `node.["town"]`, for example, choose how to obtain a JSON value from it.
let rec parseNode (options : JsonParseOption) (fieldType : SynType) (node : SynExpr) : SynExpr = /// 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
(propertyName : SynExpr option)
(options : JsonParseOption)
(fieldType : SynType)
(node : SynExpr)
: SynExpr
=
// TODO: parsing format for DateTime etc // TODO: parsing format for DateTime etc
match fieldType with match fieldType with
| DateOnly -> | DateOnly ->
asValueGetValue "string" node node
|> asValueGetValue propertyName "string"
|> SynExpr.pipeThroughFunction ( |> SynExpr.pipeThroughFunction (
SynExpr.CreateLongIdent (SynLongIdent.Create [ "System" ; "DateOnly" ; "Parse" ]) SynExpr.CreateLongIdent (SynLongIdent.Create [ "System" ; "DateOnly" ; "Parse" ])
) )
| DateTime -> | DateTime ->
asValueGetValue "string" node node
|> asValueGetValue propertyName "string"
|> SynExpr.pipeThroughFunction ( |> SynExpr.pipeThroughFunction (
SynExpr.CreateLongIdent (SynLongIdent.Create [ "System" ; "DateTime" ; "Parse" ]) SynExpr.CreateLongIdent (SynLongIdent.Create [ "System" ; "DateTime" ; "Parse" ])
) )
| NumberType typeName -> | NumberType typeName ->
let basic = asValueGetValue typeName node let basic = asValueGetValue propertyName typeName node
match options.JsonNumberHandlingArg with match options.JsonNumberHandlingArg with
| None -> basic | None -> basic
@@ -105,7 +158,7 @@ module internal JsonParseGenerator =
(SynExpr.CreateConst (SynConst.CreateString "cannot be converted to")) (SynExpr.CreateConst (SynConst.CreateString "cannot be converted to"))
let handler = let handler =
asValueGetValue "string" node asValueGetValue propertyName "string" node
|> SynExpr.pipeThroughFunction ( |> SynExpr.pipeThroughFunction (
SynExpr.CreateLongIdent (SynLongIdent.CreateFromLongIdent (parseFunction typeName)) SynExpr.CreateLongIdent (SynLongIdent.CreateFromLongIdent (parseFunction typeName))
) )
@@ -133,16 +186,16 @@ module internal JsonParseGenerator =
range0 range0
)) ))
handler handler
| PrimitiveType typeName -> asValueGetValue typeName node | PrimitiveType typeName -> asValueGetValue propertyName typeName node
| OptionType ty -> | OptionType ty ->
parseNode options ty (SynExpr.CreateIdentString "v") parseNode None options ty (SynExpr.CreateIdentString "v")
|> createParseLineOption node |> createParseLineOption node
| ListType ty -> | ListType ty ->
parseNode options ty (SynExpr.CreateLongIdent (SynLongIdent.CreateString "elt")) parseNode None options ty (SynExpr.CreateLongIdent (SynLongIdent.CreateString "elt"))
|> asArrayMapped "List" node |> asArrayMapped propertyName "List" node
| ArrayType ty -> | ArrayType ty ->
parseNode options ty (SynExpr.CreateLongIdent (SynLongIdent.CreateString "elt")) parseNode None options ty (SynExpr.CreateLongIdent (SynLongIdent.CreateString "elt"))
|> asArrayMapped "Array" node |> asArrayMapped propertyName "Array" node
| _ -> | _ ->
// Let's just hope that we've also got our own type annotation! // Let's just hope that we've also got our own type annotation!
let typeName = let typeName =
@@ -157,7 +210,7 @@ module internal JsonParseGenerator =
let createParseRhs (options : JsonParseOption) (propertyName : SynExpr) (fieldType : SynType) : SynExpr = let createParseRhs (options : JsonParseOption) (propertyName : SynExpr) (fieldType : SynType) : SynExpr =
SynExpr.CreateIdentString "node" SynExpr.CreateIdentString "node"
|> SynExpr.index propertyName |> SynExpr.index propertyName
|> parseNode options fieldType |> parseNode (Some propertyName) options fieldType
let isJsonNumberHandling (literal : LongIdent) : bool = let isJsonNumberHandling (literal : LongIdent) : bool =
match List.rev literal |> List.map (fun ident -> ident.idText) with match List.rev literal |> List.map (fun ident -> ident.idText) with