Skip to content

Commit

Permalink
patch: async handlers resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasteles committed Nov 14, 2023
1 parent 76820e6 commit 6ee9f1a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 27 deletions.
32 changes: 24 additions & 8 deletions FSharp.MinimalApi.Interop/AsParameter.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
namespace FSharp.MinimalApi;
using System.Reflection;

namespace FSharp.MinimalApi;

using Microsoft.FSharp.Core;
using Microsoft.AspNetCore.Http;

public static class AsParameters
{
public static Delegate Of<TParam, TResult>(FSharpFunc<TParam, TResult> requestDelegate) =>
typeof(TParam) == typeof(Unit)
? typeof(TResult) == typeof(Unit)
? void () => requestDelegate.Invoke(Operators.Unchecked.DefaultOf<TParam>())
: () => requestDelegate.Invoke(Operators.Unchecked.DefaultOf<TParam>())
: typeof(TResult) == typeof(Unit)
? void ([AsParameters] TParam parameters) => requestDelegate.Invoke(parameters)
: ([AsParameters] TParam parameters) => requestDelegate.Invoke(parameters);
typeof(TResult).IsGenericType &&
typeof(TResult).GetGenericTypeDefinition() == typeof(Task<>)
? CreateAsTask(requestDelegate)
: typeof(TParam) == typeof(Unit)
? typeof(TResult) == typeof(Unit)
? void () => requestDelegate.Invoke(Operators.Unchecked.DefaultOf<TParam>())
: () => requestDelegate.Invoke(Operators.Unchecked.DefaultOf<TParam>())
: typeof(TResult) == typeof(Unit)
? void ([AsParameters] TParam parameters) => requestDelegate.Invoke(parameters)
: ([AsParameters] TParam parameters) => requestDelegate.Invoke(parameters);

public static Delegate OfTask<TParam, TResult>(
FSharpFunc<TParam, Task<TResult>> requestDelegate) =>
Expand All @@ -25,4 +30,15 @@ public static Delegate OfTask<TParam, TResult>(
: typeof(TResult) == typeof(Unit)
? Task ([AsParameters] TParam parameters) => requestDelegate.Invoke(parameters)
: ([AsParameters] TParam parameters) => requestDelegate.Invoke(parameters);

static Delegate CreateAsTask<TParam, TResult>(FSharpFunc<TParam, TResult> requestDelegate)
{
var underType = typeof(TResult).GetGenericArguments()[0];
var method =
typeof(AsParameters).GetMethod(nameof(OfTask),
BindingFlags.Public | BindingFlags.Static)!
.MakeGenericMethod(typeof(TParam), underType);

return (Delegate) method.Invoke(null, new object?[] {requestDelegate})!;
}
}
21 changes: 2 additions & 19 deletions FSharp.MinimalApi/Builder/EndpointHandlerBuilder.fs
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,11 @@ type RouterBaseBuilder<'state>() =
//****************************************************************************************************
// MapGet
[<CustomOperation(HttpMethodName.Get)>]
member this.MapGet(s, route, f: Delegate, ?config) = this.get s route f config

[<CustomOperation(HttpMethodName.Get)>]
member this.MapGet(s, route, f: 'p -> 'r, ?config) =
member inline this.MapGet(s, route, f: 'p -> 'r, ?config) =
this.get s route (AsParameters.Of f) config

[<CustomOperation(HttpMethodName.Get)>]
member this.MapGet(s, route, f: 'p -> Task<'r>, ?config) =
this.get s route (AsParameters.OfTask f) config
member this.MapGet(s, route, f: Delegate, ?config) = this.get s route f config

// MapPost
[<CustomOperation(HttpMethodName.Post)>]
Expand All @@ -79,10 +75,6 @@ type RouterBaseBuilder<'state>() =
member this.MapPost(s, route, f: 'p -> 'r, ?config) =
this.post s route (AsParameters.Of f) config

[<CustomOperation(HttpMethodName.Post)>]
member this.MapPost(s, route, f: 'p -> Task<'r>, ?config) =
this.post s route (AsParameters.OfTask f) config

// MapPut
[<CustomOperation(HttpMethodName.Put)>]
member this.MapPut(s, route, f: Delegate, ?config) = this.put s route f config
Expand All @@ -91,10 +83,6 @@ type RouterBaseBuilder<'state>() =
member this.MapPut(s, route, f: 'p -> 'r, ?config) =
this.put s route (AsParameters.Of f) config

[<CustomOperation(HttpMethodName.Put)>]
member this.MapPut(s, route, f: 'p -> Task<'r>, ?config) =
this.put s route (AsParameters.OfTask f) config

// MapDelete
[<CustomOperation(HttpMethodName.Delete)>]
member this.MapDelete(s, route, f: Delegate, ?config) = this.delete s route f config
Expand All @@ -103,11 +91,6 @@ type RouterBaseBuilder<'state>() =
member this.MapDelete(s, route, f: 'p -> 'r, ?config) =
this.delete s route (AsParameters.Of f) config

[<CustomOperation(HttpMethodName.Delete)>]
member this.MapDelete(s, route, f: 'p -> Task<'r>, ?config) =
this.delete s route (AsParameters.OfTask f) config


//****************************************************************************************************
// TypedResult Maps
//****************************************************************************************************
Expand Down

0 comments on commit 6ee9f1a

Please sign in to comment.