Skip to content

Commit cbb2e77

Browse files
committed
Modified ResolverResult<'T> to use voption
1 parent b463b1b commit cbb2e77

File tree

4 files changed

+48
-37
lines changed

4 files changed

+48
-37
lines changed

src/FSharp.Data.GraphQL.Server/Execution.fs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -254,13 +254,13 @@ let private resolveField (execute: ExecuteField) (ctx: ResolveFieldContext) (par
254254
|> AsyncVal.map(fun v -> if isNull v then None else Some v)
255255

256256

257-
type ResolverResult<'T> = Result<'T * IObservable<GQLDeferredResponseContent> option * GQLProblemDetails list, GQLProblemDetails list>
257+
type ResolverResult<'T> = Result<'T * IObservable<GQLDeferredResponseContent> voption * GQLProblemDetails list, GQLProblemDetails list>
258258

259259
[<RequireQualifiedAccess>]
260260
module ResolverResult =
261261

262-
let data data = Ok (data, None, [])
263-
let defered data deferred = Ok (data, Some deferred, [])
262+
let data data = Ok (data, ValueNone, [])
263+
let defered data deferred = Ok (data, ValueSome deferred, [])
264264

265265
let mapValue (f : 'T -> 'U) (r : ResolverResult<'T>) : ResolverResult<'U> =
266266
Result.map(fun (data, deferred, errs) -> (f data, deferred, errs)) r
@@ -296,7 +296,7 @@ let deferResults path (res : ResolverResult<obj>) : IObservable<GQLDeferredRespo
296296
| [] -> DeferredResult (data, formattedPath)
297297
| _ -> DeferredErrors (data, errs, formattedPath)
298298
|> Observable.singleton
299-
Option.foldBack Observable.concat deferred deferredData
299+
ValueOption.foldBack Observable.concat deferred deferredData
300300
| Error errs -> Observable.singleton <| DeferredErrors (null, errs, formattedPath)
301301

302302
/// Collect together an array of results using the appropriate execution strategy.
@@ -312,12 +312,12 @@ let collectFields (strategy : ExecutionStrategy) (rs : AsyncVal<ResolverResult<K
312312
match (r, acc) with
313313
| Ok(field, d, e), Ok(i, deferred, errs) ->
314314
Array.set data i field
315-
Ok(i - 1, Option.mergeWith Observable.merge deferred d, e @ errs)
315+
Ok(i - 1, ValueOption.mergeWith Observable.merge deferred d, e @ errs)
316316
| Error e, Ok (_, _, errs) -> Error (e @ errs)
317317
| Ok (_, _, e), Error errs -> Error (e @ errs)
318318
| Error e, Error errs -> Error (e @ errs)
319319
return
320-
Array.foldBack merge collected (Ok (data.Length - 1, None, []))
320+
Array.foldBack merge collected (Ok (data.Length - 1, ValueNone, []))
321321
|> ResolverResult.mapValue(fun _ -> data)
322322
}
323323

@@ -363,7 +363,7 @@ let rec private direct (returnDef : OutputDef) (ctx : ResolveFieldContext) (path
363363
| Nullable (Output innerDef) ->
364364
let innerCtx = { ctx with ExecutionInfo = { ctx.ExecutionInfo with IsNullable = true; ReturnDef = innerDef } }
365365
executeResolvers innerCtx path parent (toOption value |> AsyncVal.wrap)
366-
|> AsyncVal.map(Result.valueOr (fun errs -> (KeyValuePair(name, null), None, errs)) >> Ok)
366+
|> AsyncVal.map(Result.valueOr (fun errs -> (KeyValuePair(name, null), ValueNone, errs)) >> Ok)
367367

368368
| Interface iDef ->
369369
let possibleTypesFn = ctx.Schema.GetPossibleTypes
@@ -398,7 +398,7 @@ and deferred (ctx : ResolveFieldContext) (path : FieldPath) (parent : obj) (valu
398398
executeResolvers ctx path parent (toOption value |> AsyncVal.wrap)
399399
|> Observable.ofAsyncVal
400400
|> Observable.bind(ResolverResult.mapValue(fun d -> d.Value) >> deferResults path)
401-
ResolverResult.defered (KeyValuePair (info.Identifier, null)) deferred |> AsyncVal.wrap
401+
ResolverResult.defered (KeyValuePair (name, null)) deferred |> AsyncVal.wrap
402402

403403
and private streamed (options : BufferedStreamOptions) (innerDef : OutputDef) (ctx : ResolveFieldContext) (path : FieldPath) (parent : obj) (value : obj) =
404404
let info = ctx.ExecutionInfo
@@ -420,9 +420,9 @@ and private streamed (options : BufferedStreamOptions) (innerDef : OutputDef) (c
420420
match r with
421421
| Ok (item, d, e) ->
422422
Array.set data i item.Value
423-
(i - 1, box index :: indicies, Option.mergeWith Observable.merge deferred d, e @ errs)
423+
(i - 1, box index :: indicies, ValueOption.mergeWith Observable.merge deferred d, e @ errs)
424424
| Error e -> (i - 1, box index :: indicies, deferred, e @ errs)
425-
let (_, indicies, deferred, errs) = List.foldBack merge chunk (chunk.Length - 1, [], None, [])
425+
let (_, indicies, deferred, errs) = List.foldBack merge chunk (chunk.Length - 1, [], ValueNone, [])
426426
deferResults (box indicies :: path) (Ok (box data, deferred, errs))
427427

428428
let buffer (items : IObservable<int * ResolverResult<KeyValuePair<string, obj>>>) : IObservable<GQLDeferredResponseContent> =
@@ -449,8 +449,8 @@ and private streamed (options : BufferedStreamOptions) (innerDef : OutputDef) (c
449449
|> Array.mapi resolveItem
450450
|> Observable.ofAsyncValSeq
451451
|> buffer
452-
ResolverResult.defered (KeyValuePair (info.Identifier, box [])) stream |> AsyncVal.wrap
453-
| _ -> raise <| GQLMessageException (ErrorMessages.expectedEnumerableValue ctx.ExecutionInfo.Identifier (value.GetType()))
452+
ResolverResult.defered (KeyValuePair (name, box [])) stream |> AsyncVal.wrap
453+
| _ -> raise <| GQLMessageException (ErrorMessages.expectedEnumerableValue name (value.GetType()))
454454

455455
and private live (ctx : ResolveFieldContext) (path : FieldPath) (parent : obj) (value : obj) =
456456
let info = ctx.ExecutionInfo
@@ -485,7 +485,7 @@ and private live (ctx : ResolveFieldContext) (path : FieldPath) (parent : obj) (
485485

486486
executeResolvers ctx path parent (value |> Some |> AsyncVal.wrap)
487487
// TODO: Add tests for `Observable.merge deferred updates` correct order
488-
|> AsyncVal.map(Result.map(fun (data, deferred, errs) -> (data, Some <| Option.foldBack Observable.merge deferred updates, errs)))
488+
|> AsyncVal.map(Result.map(fun (data, deferred, errs) -> (data, ValueSome <| ValueOption.foldBack Observable.merge deferred updates, errs)))
489489

490490
/// Actually execute the resolvers.
491491
and private executeResolvers (ctx : ResolveFieldContext) (path : FieldPath) (parent : obj) (value : AsyncVal<obj option>) : AsyncVal<ResolverResult<KeyValuePair<string, obj>>> =
@@ -505,8 +505,8 @@ and private executeResolvers (ctx : ResolveFieldContext) (path : FieldPath) (par
505505
let resolveWith (ctx : ResolveFieldContext) (onSuccess : ResolveFieldContext -> FieldPath -> obj -> obj -> AsyncVal<ResolverResult<KeyValuePair<string, obj>>>) : AsyncVal<ResolverResult<KeyValuePair<string, obj>>> = asyncVal {
506506
let! resolved = value |> AsyncVal.rescue path ctx.Schema.ParseError
507507
match resolved with
508-
| Error errs when ctx.ExecutionInfo.IsNullable -> return Ok (KeyValuePair(name, null), None, errs)
509-
| Ok None when ctx.ExecutionInfo.IsNullable -> return Ok (KeyValuePair(name, null), None, [])
508+
| Error errs when ctx.ExecutionInfo.IsNullable -> return Ok (KeyValuePair(name, null), ValueNone, errs)
509+
| Ok None when ctx.ExecutionInfo.IsNullable -> return Ok (KeyValuePair(name, null), ValueNone, [])
510510
| Error errs -> return Error errs
511511
| Ok None -> return Error (nullResolverError name path ctx)
512512
| Ok (Some v) -> return! onSuccess ctx path parent v
@@ -604,16 +604,16 @@ let private executeQueryOrMutation (resultSet: (string * ExecutionInfo) []) (ctx
604604
| Ok (Error errs)
605605
| Error errs -> Error errs
606606
match result with
607-
| Error errs when info.IsNullable -> return Ok (KeyValuePair(name, null), None, errs)
607+
| Error errs when info.IsNullable -> return Ok (KeyValuePair(name, null), ValueNone, errs)
608608
| Error errs -> return Error errs
609609
| Ok r -> return Ok r
610610
}
611611

612612
asyncVal {
613613
let documentId = ctx.ExecutionPlan.DocumentId
614-
match! resultSet |> Array.map executeRootOperation |> collectFields ctx.ExecutionPlan.Strategy with
615-
| Ok (data, Some deferred, errs) -> return GQLExecutionResult.Deferred(documentId, NameValueLookup(data), errs, deferred, ctx.Metadata)
616-
| Ok (data, None, errs) -> return GQLExecutionResult.Direct(documentId, NameValueLookup(data), errs, ctx.Metadata)
614+
match! resultSet |> Seq.map executeRootOperation |> collectFields ctx.ExecutionPlan.Strategy with
615+
| Ok (data, ValueSome deferred, errs) -> return GQLExecutionResult.Deferred(documentId, NameValueLookup(data), errs, deferred, ctx.Metadata)
616+
| Ok (data, ValueNone, errs) -> return GQLExecutionResult.Direct(documentId, NameValueLookup(data), errs, ctx.Metadata)
617617
| Error errs -> return GQLExecutionResult.RequestError(documentId, errs, ctx.Metadata)
618618
}
619619

@@ -635,9 +635,9 @@ let private executeSubscription (resultSet: (string * ExecutionInfo) []) (ctx: E
635635
Path = fieldPath |> List.rev }
636636
let onValue v = asyncVal {
637637
match! executeResolvers fieldCtx fieldPath value (toOption v |> AsyncVal.wrap) with
638-
| Ok (data, None, []) -> return SubscriptionResult (NameValueLookup.ofList [nameOrAlias, data.Value])
639-
| Ok (data, None, errs) -> return SubscriptionErrors (NameValueLookup.ofList [nameOrAlias, data.Value], errs)
640-
| Ok (_, Some _, _) -> return failwith "Deferred/Streamed/Live are not supported for subscriptions!"
638+
| Ok (data, ValueNone, []) -> return SubscriptionResult (NameValueLookup.ofList [nameOrAlias, data.Value])
639+
| Ok (data, ValueNone, errs) -> return SubscriptionErrors (NameValueLookup.ofList [nameOrAlias, data.Value], errs)
640+
| Ok (_, ValueSome _, _) -> return failwith "Deferred/Streamed/Live are not supported for subscriptions!"
641641
| Error errs -> return SubscriptionErrors (null, errs)
642642
}
643643
return

src/FSharp.Data.GraphQL.Shared/Helpers/Extensions.fs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,6 @@ type TypeInfo with
3939
x.GetDeclaredMethod(first + propertyName.Substring(1))
4040
| prop, _ -> prop
4141

42-
module Option =
43-
44-
let mergeWith (f: 'T -> 'T -> 'T) (o1 : 'T option) (o2 : 'T option) : 'T option =
45-
match (o1, o2) with
46-
| Some a, Some b -> Some (f a b)
47-
| Some a, _ -> Some a
48-
| _, Some b -> Some b
49-
| _, _ -> None
50-
51-
let unwrap (defaultValue : 'U) (onSome : 'T -> 'U) (o : 'T option) : 'U =
52-
match o with
53-
| Some t -> onSome t
54-
| None -> defaultValue
55-
5642
module Skippable =
5743

5844
let ofList list =

src/FSharp.Data.GraphQL.Shared/Helpers/ObjAndStructConversions.fs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@ module internal ValueOption =
99

1010
let ofOption value = Option.toVOption value
1111

12+
let mergeWith (f: 'T -> 'T -> 'T) (o1 : 'T voption) (o2 : 'T voption) : 'T voption =
13+
match (o1, o2) with
14+
| ValueSome a, ValueSome b -> ValueSome (f a b)
15+
| ValueSome a, _ -> ValueSome a
16+
| _, ValueSome b -> ValueSome b
17+
| _, _ -> ValueNone
18+
19+
let unwrap (defaultValue : 'U) (onSome : 'T -> 'U) (o : 'T voption) : 'U =
20+
match o with
21+
| ValueSome t -> onSome t
22+
| ValueNone -> defaultValue
23+
1224
module internal Option =
1325

1426
let toVOption voption =
@@ -18,6 +30,18 @@ module internal Option =
1830

1931
let ofVOption voption = voption |> ValueOption.toOption
2032

33+
let mergeWith (f: 'T -> 'T -> 'T) (o1 : 'T option) (o2 : 'T option) : 'T option =
34+
match (o1, o2) with
35+
| Some a, Some b -> Some (f a b)
36+
| Some a, _ -> Some a
37+
| _, Some b -> Some b
38+
| _, _ -> None
39+
40+
let unwrap (defaultValue : 'U) (onSome : 'T -> 'U) (o : 'T option) : 'U =
41+
match o with
42+
| Some t -> onSome t
43+
| None -> defaultValue
44+
2145
[<AutoOpen>]
2246
module internal ValueTuple =
2347

src/FSharp.Data.GraphQL.Shared/TypeSystem.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,8 @@ and ExecutionInfoKind =
747747
/// Reduce the current field as a live query.
748748
| ResolveLive of ExecutionInfo
749749

750-
/// Buffered stream options. Used to specify how the buffer will behavior in a stream.
750+
// TODO: Migrate to voption
751+
/// Buffered stream options. Used to specify how the buffer will behave in a stream.
751752
and BufferedStreamOptions =
752753
{ /// The maximum time in milliseconds that the buffer will be filled before being sent to the subscriber.
753754
Interval : int option

0 commit comments

Comments
 (0)