Skip to content

Commit

Permalink
Fix json provider PreferDictionaries for array properties
Browse files Browse the repository at this point in the history
  • Loading branch information
mlaily committed Mar 5, 2023
1 parent ba95b6a commit 47122e2
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 202 deletions.
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Move common runtime utilities out of `FSharp.Data.Http` and into a new `FSharp.Data.Runtime.Utilities` assembly.
* Add `aria-label` to the list of html attributes used to infer names of types provided by the HtmlProvider.
* Enable TLS 1.2 when requesting http(s) samples from the type providers.
* Fix generated code of the json provider with `PreferDictionaries` when values are arrays.

### 6.0.1-beta001 - Aug 18 2022

Expand Down
41 changes: 35 additions & 6 deletions src/FSharp.Data.DesignTime/Json/JsonGenerator.fs
Original file line number Diff line number Diff line change
Expand Up @@ -399,15 +399,42 @@ module JsonTypeBuilder =
let inferedKeyValueType =
let aggr = List.fold (StructuralInference.subtypeInfered false) InferedType.Top

let dropRecordName infType =
let dropRecordsNames infType =

let dropRecordName infType =
match infType with
| InferedType.Record (_, fields, opt) -> InferedType.Record(None, fields, opt)
| _ -> infType

let dropTagName tag =
match tag with
| InferedTypeTag.Record (Some _) -> InferedTypeTag.Record None
| _ -> tag

let infType = dropRecordName infType

match infType with
| InferedType.Record (_, fields, opt) -> InferedType.Record(None, fields, opt)
| InferedType.Collection (order, types) ->
// Records in collections have the parent property as name.
// We drop it too so they can be merged into a unified type.
let order = order |> List.map dropTagName

let types =
types
|> Map.toSeq
|> Seq.map (fun (tag, (multiplicity, typ)) ->
let tag = dropTagName tag
let typ = dropRecordName typ
tag, (multiplicity, typ))
|> Map.ofSeq

InferedType.Collection(order, types)
| _ -> infType

if not ctx.PreferDictionaries then
None
else
let infType =
let infKeyType =
[ for prop in props ->
StructuralInference.getInferedTypeFromString
ctx.UnitsOfMeasureProvider
Expand All @@ -417,14 +444,16 @@ module JsonTypeBuilder =
None ]
|> aggr

match infType with
match infKeyType with
| InferedType.Primitive (typ = typ) when typ <> typeof<string> ->
let inferValueType =
([ for prop in props -> prop.Type |> dropRecordName ]
([ for prop in props -> prop.Type |> dropRecordsNames ]
|> aggr)
// Optional properties in the initial record should translate
// to simply missing values in the dictionary, not an optional type.
.DropOptionality()

(infType, inferValueType) |> Some
Some(infKeyType, inferValueType)
| _ -> None

match inferedKeyValueType with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class JsonProvider+Root : FDR.BaseTypes.IJsonDocument


class JsonProvider+Mappings : FDR.BaseTypes.IJsonDocument
new : items:int * JsonProvider+MappingsValue seq -> JsonProvider+Mappings
new : items:int * JsonProvider+JsonProvider+MappingsValue[] seq -> JsonProvider+Mappings
JsonRuntime.CreateRecordFromDictionary(items, "", new Func<_,_>(fun (t:int) -> TextRuntime.ConvertIntegerBack("", Some t)))

new : jsonValue:JsonValue -> JsonProvider+Mappings
Expand All @@ -57,70 +57,32 @@ class JsonProvider+Mappings : FDR.BaseTypes.IJsonDocument
member IsEmpty: bool with get
(Operators.op_Equality JsonRuntime.GetRecordProperties(this).Length 0)

member Item: JsonProvider+MappingsValue with get
JsonRuntime.GetValueByKeyFromInferedDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.GetNonOptionalValue(t.Path(), JsonRuntime.ConvertInteger("", Some t.JsonValue), Some t.JsonValue)), new Func<_,_>(id)), key)
member Item: JsonProvider+JsonProvider+MappingsValue[] with get
JsonRuntime.GetValueByKeyFromInferedDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.GetNonOptionalValue(t.Path(), JsonRuntime.ConvertInteger("", Some t.JsonValue), Some t.JsonValue)), new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.ConvertArray(t, new Func<_,_>(id)))), key)

member Items: int * JsonProvider+MappingsValue seq with get
JsonRuntime.ConvertRecordToDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.GetNonOptionalValue(t.Path(), JsonRuntime.ConvertInteger("", Some t.JsonValue), Some t.JsonValue)), new Func<_,_>(id)))
member Items: int * JsonProvider+JsonProvider+MappingsValue[] seq with get
JsonRuntime.ConvertRecordToDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.GetNonOptionalValue(t.Path(), JsonRuntime.ConvertInteger("", Some t.JsonValue), Some t.JsonValue)), new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.ConvertArray(t, new Func<_,_>(id)))))

member Keys: int[] with get
JsonRuntime.GetKeysFromInferedDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.GetNonOptionalValue(t.Path(), JsonRuntime.ConvertInteger("", Some t.JsonValue), Some t.JsonValue)))

member TryFind: key:int -> JsonProvider+MappingsValue option
JsonRuntime.TryGetValueByKeyFromInferedDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.GetNonOptionalValue(t.Path(), JsonRuntime.ConvertInteger("", Some t.JsonValue), Some t.JsonValue)), new Func<_,_>(id)), key)
member TryFind: key:int -> JsonProvider+JsonProvider+MappingsValue[] option
JsonRuntime.TryGetValueByKeyFromInferedDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.GetNonOptionalValue(t.Path(), JsonRuntime.ConvertInteger("", Some t.JsonValue), Some t.JsonValue)), new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.ConvertArray(t, new Func<_,_>(id)))), key)

member Values: JsonProvider+JsonProvider+MappingsValue[] with get
JsonRuntime.GetValuesFromInferedDictionary(this, new Func<_,_>(id)))
member Values: JsonProvider+JsonProvider+JsonProvider+MappingsValue[][] with get
JsonRuntime.GetValuesFromInferedDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.ConvertArray(t, new Func<_,_>(id)))))


class JsonProvider+MappingsValue : FDR.BaseTypes.IJsonDocument
new : 123s:JsonProvider+JsonProvider+123[] -> record:JsonProvider+123 option -> 789s:JsonProvider+JsonProvider+789[] -> JsonProvider+MappingsValue
JsonRuntime.CreateArray([| (123s :> obj)
(record :> obj)
(789s :> obj) |], "")

new : jsonValue:JsonValue -> JsonProvider+MappingsValue
JsonDocument.Create(jsonValue, "")

member 123s: JsonProvider+JsonProvider+123[] with get
JsonRuntime.GetArrayChildrenByTypeTag(this, "", "Record@123", new Func<_,_>(id)))

member 789s: JsonProvider+JsonProvider+789[] with get
JsonRuntime.GetArrayChildrenByTypeTag(this, "", "Record@789", new Func<_,_>(id)))

member Record: JsonProvider+123 option with get
JsonRuntime.TryGetArrayChildByTypeTag(this, "", "Record@456", new Func<_,_>(id)))


class JsonProvider+123 : FDR.BaseTypes.IJsonDocument
new : groupId:int -> canDelete:bool -> JsonProvider+123
JsonRuntime.CreateRecord([| ("GroupId",
(groupId :> obj))
("CanDelete",
(canDelete :> obj)) |], "")

new : jsonValue:JsonValue -> JsonProvider+123
JsonDocument.Create(jsonValue, "")

member CanDelete: bool with get
let value = JsonRuntime.TryGetPropertyUnpackedWithPath(this, "CanDelete")
JsonRuntime.GetNonOptionalValue(value.Path, JsonRuntime.ConvertBoolean(value.JsonOpt), value.JsonOpt)

member GroupId: int with get
let value = JsonRuntime.TryGetPropertyUnpackedWithPath(this, "GroupId")
JsonRuntime.GetNonOptionalValue(value.Path, JsonRuntime.ConvertInteger("", value.JsonOpt), value.JsonOpt)


class JsonProvider+789 : FDR.BaseTypes.IJsonDocument
new : groupId:int -> canDelete:bool -> errorMessage:string option -> JsonProvider+789
new : groupId:int -> canDelete:bool -> errorMessage:string option -> JsonProvider+MappingsValue
JsonRuntime.CreateRecord([| ("GroupId",
(groupId :> obj))
("CanDelete",
(canDelete :> obj))
("ErrorMessage",
(errorMessage :> obj)) |], "")

new : jsonValue:JsonValue -> JsonProvider+789
new : jsonValue:JsonValue -> JsonProvider+MappingsValue
JsonDocument.Create(jsonValue, "")

member CanDelete: bool with get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class JsonProvider+Root : FDR.BaseTypes.IJsonDocument


class JsonProvider+Mappings : FDR.BaseTypes.IJsonDocument
new : items:int * JsonProvider+MappingsValue seq -> JsonProvider+Mappings
new : items:int * JsonProvider+JsonProvider+MappingsValue[] seq -> JsonProvider+Mappings
JsonRuntime.CreateRecordFromDictionary(items, "", new Func<_,_>(fun (t:int) -> TextRuntime.ConvertIntegerBack("", Some t)))

new : jsonValue:JsonValue -> JsonProvider+Mappings
Expand All @@ -57,70 +57,32 @@ class JsonProvider+Mappings : FDR.BaseTypes.IJsonDocument
member IsEmpty: bool with get
(Operators.op_Equality JsonRuntime.GetRecordProperties(this).Length 0)

member Item: JsonProvider+MappingsValue with get
JsonRuntime.GetValueByKeyFromInferedDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.GetNonOptionalValue(t.Path(), JsonRuntime.ConvertInteger("", Some t.JsonValue), Some t.JsonValue)), new Func<_,_>(id)), key)
member Item: JsonProvider+JsonProvider+MappingsValue[] with get
JsonRuntime.GetValueByKeyFromInferedDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.GetNonOptionalValue(t.Path(), JsonRuntime.ConvertInteger("", Some t.JsonValue), Some t.JsonValue)), new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.ConvertArray(t, new Func<_,_>(id)))), key)

member Items: int * JsonProvider+MappingsValue seq with get
JsonRuntime.ConvertRecordToDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.GetNonOptionalValue(t.Path(), JsonRuntime.ConvertInteger("", Some t.JsonValue), Some t.JsonValue)), new Func<_,_>(id)))
member Items: int * JsonProvider+JsonProvider+MappingsValue[] seq with get
JsonRuntime.ConvertRecordToDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.GetNonOptionalValue(t.Path(), JsonRuntime.ConvertInteger("", Some t.JsonValue), Some t.JsonValue)), new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.ConvertArray(t, new Func<_,_>(id)))))

member Keys: int[] with get
JsonRuntime.GetKeysFromInferedDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.GetNonOptionalValue(t.Path(), JsonRuntime.ConvertInteger("", Some t.JsonValue), Some t.JsonValue)))

member TryFind: key:int -> JsonProvider+MappingsValue option
JsonRuntime.TryGetValueByKeyFromInferedDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.GetNonOptionalValue(t.Path(), JsonRuntime.ConvertInteger("", Some t.JsonValue), Some t.JsonValue)), new Func<_,_>(id)), key)
member TryFind: key:int -> JsonProvider+JsonProvider+MappingsValue[] option
JsonRuntime.TryGetValueByKeyFromInferedDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.GetNonOptionalValue(t.Path(), JsonRuntime.ConvertInteger("", Some t.JsonValue), Some t.JsonValue)), new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.ConvertArray(t, new Func<_,_>(id)))), key)

member Values: JsonProvider+JsonProvider+MappingsValue[] with get
JsonRuntime.GetValuesFromInferedDictionary(this, new Func<_,_>(id)))
member Values: JsonProvider+JsonProvider+JsonProvider+MappingsValue[][] with get
JsonRuntime.GetValuesFromInferedDictionary(this, new Func<_,_>(fun (t:IJsonDocument) -> JsonRuntime.ConvertArray(t, new Func<_,_>(id)))))


class JsonProvider+MappingsValue : FDR.BaseTypes.IJsonDocument
new : 123s:JsonProvider+JsonProvider+123[] -> record:JsonProvider+123 option -> 789s:JsonProvider+JsonProvider+789[] -> JsonProvider+MappingsValue
JsonRuntime.CreateArray([| (123s :> obj)
(record :> obj)
(789s :> obj) |], "")

new : jsonValue:JsonValue -> JsonProvider+MappingsValue
JsonDocument.Create(jsonValue, "")

member 123s: JsonProvider+JsonProvider+123[] with get
JsonRuntime.GetArrayChildrenByTypeTag(this, "", "Record@123", new Func<_,_>(id)))

member 789s: JsonProvider+JsonProvider+789[] with get
JsonRuntime.GetArrayChildrenByTypeTag(this, "", "Record@789", new Func<_,_>(id)))

member Record: JsonProvider+123 option with get
JsonRuntime.TryGetArrayChildByTypeTag(this, "", "Record@456", new Func<_,_>(id)))


class JsonProvider+123 : FDR.BaseTypes.IJsonDocument
new : groupId:int -> canDelete:bool -> JsonProvider+123
JsonRuntime.CreateRecord([| ("GroupId",
(groupId :> obj))
("CanDelete",
(canDelete :> obj)) |], "")

new : jsonValue:JsonValue -> JsonProvider+123
JsonDocument.Create(jsonValue, "")

member CanDelete: bool with get
let value = JsonRuntime.TryGetPropertyUnpackedWithPath(this, "CanDelete")
JsonRuntime.GetNonOptionalValue(value.Path, JsonRuntime.ConvertBoolean(value.JsonOpt), value.JsonOpt)

member GroupId: int with get
let value = JsonRuntime.TryGetPropertyUnpackedWithPath(this, "GroupId")
JsonRuntime.GetNonOptionalValue(value.Path, JsonRuntime.ConvertInteger("", value.JsonOpt), value.JsonOpt)


class JsonProvider+789 : FDR.BaseTypes.IJsonDocument
new : groupId:int -> canDelete:bool -> errorMessage:string option -> JsonProvider+789
new : groupId:int -> canDelete:bool -> errorMessage:string option -> JsonProvider+MappingsValue
JsonRuntime.CreateRecord([| ("GroupId",
(groupId :> obj))
("CanDelete",
(canDelete :> obj))
("ErrorMessage",
(errorMessage :> obj)) |], "")

new : jsonValue:JsonValue -> JsonProvider+789
new : jsonValue:JsonValue -> JsonProvider+MappingsValue
JsonDocument.Create(jsonValue, "")

member CanDelete: bool with get
Expand Down
Loading

0 comments on commit 47122e2

Please sign in to comment.