Skip to content

Commit

Permalink
Simplified isAssignableWithUnwrap implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
xperiandri committed Dec 7, 2024
1 parent 15150f1 commit ff6221b
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 17 deletions.
15 changes: 7 additions & 8 deletions src/FSharp.Data.GraphQL.Server/ReflectionHelper.fs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ module internal ReflectionHelper =
ty.GetGenericArguments().[0]
else ty

let isAssignableWithUnwrap (from: Type) (``to``: Type) =
let rec isAssignableWithUnwrap (from: Type) (``to``: Type) =

let checkCollections (from: Type) (``to``: Type) =
if
Expand All @@ -176,17 +176,16 @@ module internal ReflectionHelper =
from.GetGenericArguments()[0]
else from
let actualTo =
if ``to``.FullName.StartsWith OptionTypeName || ``to``.FullName.StartsWith ValueOptionTypeName then
if ``to``.FullName.StartsWith OptionTypeName ||
``to``.FullName.StartsWith ValueOptionTypeName
then
``to``.GetGenericArguments()[0]
else ``to``

let result = actualFrom.IsAssignableTo actualTo || checkCollections actualFrom actualTo
if result then result
else
if actualFrom.FullName.StartsWith OptionTypeName || actualFrom.FullName.StartsWith ValueOptionTypeName then
let actualFrom = actualFrom.GetGenericArguments()[0]
actualFrom.IsAssignableTo actualTo || checkCollections actualFrom actualTo
else result
if result then true
elif actualFrom <> from || actualTo <> ``to`` then isAssignableWithUnwrap actualFrom actualTo
else false

let matchConstructor (t: Type) (fields: string []) =
if FSharpType.IsRecord(t, true) then FSharpValue.PreComputeRecordConstructorInfo(t, true)
Expand Down
18 changes: 9 additions & 9 deletions src/FSharp.Data.GraphQL.Shared/Validation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,9 @@ module Ast =
|> ValueOption.map _.TypeCondition
|> ValueOption.defaultValue x.ParentType

let private tryFindInArrayOption (finder : 'T -> bool) = ValueOption.ofOption >> ValueOption.bind (Array.tryFind finder >> ValueOption.ofOption)
let private tryFindInArrayOption (finder : 'T -> bool) =
ValueOption.ofOption
>> ValueOption.bind (Array.tryFind finder >> ValueOption.ofOption)

let private onAllSelections (ctx : ValidationContext) (onSelection : SelectionInfo -> ValidationResult<GQLProblemDetails>) =
let rec traverseSelections selection =
Expand Down Expand Up @@ -360,7 +362,9 @@ module Ast =
|> ValueOption.defaultValue List.empty
| FragmentSpread fragSpread ->
voption {
let! fragDef = ctx.FragmentDefinitions |> List.tryFind (fun def -> def.Name.IsSome && def.Name.Value = fragSpread.Name)
let! fragDef =
ctx.FragmentDefinitions
|> List.tryFind (fun def -> def.Name.IsSome && def.Name.Value = fragSpread.Name)
let! typeCondition = fragDef.TypeCondition
let! fragType = ctx.Schema.TryGetTypeByName typeCondition
let fragType = Spread (fragSpread.Name, fragSpread.Directives, fragType)
Expand Down Expand Up @@ -898,10 +902,6 @@ module Ast =
|> ValidationResult.collect (checkFragmentSpreadIsPossibleInSelection))

let private checkInputValue (schemaInfo : SchemaInfo) (variables : VariableDefinition list option) (selection : SelectionInfo) =
let rec getFieldMap (fields : (string * IntrospectionTypeRef) seq) : Map<string, IntrospectionTypeRef> =
(Map.empty, fields)
||> Seq.fold (fun acc (name, tref) -> Map.add name tref acc)

let rec checkIsCoercible (tref : IntrospectionTypeRef) (argName : string) (value : InputValue) =
let canNotCoerce =
AstError.AsResult (
Expand Down Expand Up @@ -954,8 +954,7 @@ module Ast =
let fieldMap =
itype.InputFields
|> Option.defaultValue [||]
|> Array.map (fun x -> x.Name, x.Type)
|> getFieldMap
|> Array.fold (fun acc inputVal -> Map.add inputVal.Name inputVal.Type acc) Map.empty
let canCoerceFields =
fieldMap
|> ValidationResult.collect (fun kvp ->
Expand Down Expand Up @@ -1401,7 +1400,8 @@ module Ast =
| ValueSome operationName, _ ->
AstError.AsResult
$"A variable '$%s{varDef.VariableName}' is not used in operation '%s{operationName}'. Every variable must be used."
| ValueNone, _ -> AstError.AsResult $"A variable '$%s{varDef.VariableName}' is not used in operation. Every variable must be used.")
| ValueNone, _ ->
AstError.AsResult $"A variable '$%s{varDef.VariableName}' is not used in operation. Every variable must be used.")
| _ -> Success)

let rec private areTypesCompatible (variableTypeRef : IntrospectionTypeRef) (locationTypeRef : IntrospectionTypeRef) =
Expand Down

0 comments on commit ff6221b

Please sign in to comment.