Skip to content

Commit 74f132a

Browse files
committed
Added support for return codes from synchronous handler functions
1 parent 836063b commit 74f132a

File tree

1 file changed

+56
-6
lines changed

1 file changed

+56
-6
lines changed

src/FSharp.SystemCommandLine/CommandBuilders.fs

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ open System.CommandLine.Builder
99
open System.CommandLine.Parsing
1010

1111
type private HI<'T> = HandlerInput<'T>
12+
type private IC = System.CommandLine.Invocation.InvocationContext
1213
let private def<'T> = Unchecked.defaultof<'T>
1314

1415
type CommandSpec<'Inputs, 'Output> =
@@ -170,8 +171,43 @@ type BaseCommandBuilder<'A, 'B, 'C, 'D, 'E, 'F, 'G, 'H, 'I, 'J, 'K, 'L, 'M, 'N,
170171
| _ -> raise (NotImplementedException())
171172
cmd
172173

174+
/// Sets a command handler that returns a status code.
175+
member this.SetFuncHandlerSync (spec: CommandSpec<'Inputs, int>) (cmd: Command) =
176+
let handler (args: obj) =
177+
spec.Handler (args :?> 'Inputs)
178+
179+
let inputs =
180+
spec.Inputs
181+
|> List.choose (fun input ->
182+
match input.Source with
183+
| ParsedOption o -> o :> IValueDescriptor |> Some
184+
| ParsedArgument a -> a :> IValueDescriptor |> Some
185+
| InjectedDependency -> None
186+
)
187+
|> List.toArray
188+
189+
match spec.Inputs.Length with
190+
| 00 -> cmd.SetHandler(Action<IC>(fun ctx -> ctx.ExitCode <- handler ()))
191+
| 01 -> cmd.SetHandler(Action<IC, 'A>(fun ctx a -> ctx.ExitCode <- handler (a)), inputs)
192+
| 02 -> cmd.SetHandler(Action<IC, 'A, 'B>(fun ctx a b -> ctx.ExitCode <- handler (a, b)), inputs)
193+
| 03 -> cmd.SetHandler(Action<IC, 'A, 'B, 'C>(fun ctx a b c -> ctx.ExitCode <- handler (a, b, c)), inputs)
194+
| 04 -> cmd.SetHandler(Action<IC, 'A, 'B, 'C, 'D>(fun ctx a b c d -> ctx.ExitCode <- handler (a, b, c, d)), inputs)
195+
| 05 -> cmd.SetHandler(Action<IC, 'A, 'B, 'C, 'D, 'E>(fun ctx a b c d e -> ctx.ExitCode <- handler (a, b, c, d, e)), inputs)
196+
| 06 -> cmd.SetHandler(Action<IC, 'A, 'B, 'C, 'D, 'E, 'F>(fun ctx a b c d e f -> ctx.ExitCode <- handler (a, b, c, d, e, f)), inputs)
197+
| 07 -> cmd.SetHandler(Action<IC, 'A, 'B, 'C, 'D, 'E, 'F, 'G>(fun ctx a b c d e f g -> ctx.ExitCode <- handler (a, b, c, d, e, f, g)), inputs)
198+
| 08 -> cmd.SetHandler(Action<IC, 'A, 'B, 'C, 'D, 'E, 'F, 'G, 'H>(fun ctx a b c d e f g h -> ctx.ExitCode <- handler (a, b, c, d, e, f, g, h)), inputs)
199+
| 09 -> cmd.SetHandler(Action<IC, 'A, 'B, 'C, 'D, 'E, 'F, 'G, 'H, 'I>(fun ctx a b c d e f g h i -> ctx.ExitCode <- handler (a, b, c, d, e, f, g, h, i)), inputs)
200+
| 10 -> cmd.SetHandler(Action<IC, 'A, 'B, 'C, 'D, 'E, 'F, 'G, 'H, 'I, 'J>(fun ctx a b c d e f g h i j -> ctx.ExitCode <- handler (a, b, c, d, e, f, g, h, i, j)), inputs)
201+
| 11 -> cmd.SetHandler(Action<IC, 'A, 'B, 'C, 'D, 'E, 'F, 'G, 'H, 'I, 'J, 'K>(fun ctx a b c d e f g h i j k -> ctx.ExitCode <- handler (a, b, c, d, e, f, g, h, i, j, k)), inputs)
202+
| 12 -> cmd.SetHandler(Action<IC, 'A, 'B, 'C, 'D, 'E, 'F, 'G, 'H, 'I, 'J, 'K, 'L>(fun ctx a b c d e f g h i j k l -> ctx.ExitCode <- handler (a, b, c, d, e, f, g, h, i, j, k, l)), inputs)
203+
| 13 -> cmd.SetHandler(Action<IC, 'A, 'B, 'C, 'D, 'E, 'F, 'G, 'H, 'I, 'J, 'K, 'L, 'M>(fun ctx a b c d e f g h i j k l m -> ctx.ExitCode <- handler (a, b, c, d, e, f, g, h, i, j, k, l, m)), inputs)
204+
| 14 -> cmd.SetHandler(Action<IC, 'A, 'B, 'C, 'D, 'E, 'F, 'G, 'H, 'I, 'J, 'K, 'L, 'M, 'N>(fun ctx a b c d e f g h i j k l m n -> ctx.ExitCode <- handler (a, b, c, d, e, f, g, h, i, j, k, l, m, n)), inputs)
205+
| 15 -> cmd.SetHandler(Action<IC, 'A, 'B, 'C, 'D, 'E, 'F, 'G, 'H, 'I, 'J, 'K, 'L, 'M, 'N, 'O>(fun ctx a b c d e f g h i j k l m n o -> ctx.ExitCode <- handler (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)), inputs)
206+
| _ -> raise (NotImplementedException())
207+
cmd
208+
173209
/// Sets a command handler that returns a Task.
174-
member this.SetFuncHandler (spec: CommandSpec<'Inputs, Task<'ReturnValue>>) (cmd: Command) =
210+
member this.SetFuncHandlerAsync (spec: CommandSpec<'Inputs, Task<'ReturnValue>>) (cmd: Command) =
175211
let handler (args: obj) =
176212
task {
177213
return! spec.Handler (args :?> 'Inputs)
@@ -231,14 +267,22 @@ type RootCommandBuilder<'A, 'B, 'C, 'D, 'E, 'F, 'G, 'H, 'I, 'J, 'K, 'L, 'M, 'N,
231267
|> ignore
232268
this.CommandLineBuilder.Build().Parse(args).Invoke()
233269

234-
/// Executes a Command with a handler that returns a Task.
270+
/// Executes a Command with a handler that returns int.
271+
member this.Run (spec: CommandSpec<'Inputs, int>) =
272+
this.CommandLineBuilder.Command
273+
|> this.SetGeneralProperties spec
274+
|> this.SetFuncHandlerSync spec
275+
|> ignore
276+
this.CommandLineBuilder.Build().Parse(args).Invoke()
277+
278+
/// Executes a Command with a handler that returns a Task<unit> or Task<int>.
235279
member this.Run (spec: CommandSpec<'Inputs, Task<'ReturnValue>>) =
236280
this.CommandLineBuilder.Command
237281
|> this.SetGeneralProperties spec
238-
|> this.SetFuncHandler spec
282+
|> this.SetFuncHandlerAsync spec
239283
|> ignore
240284
this.CommandLineBuilder.Build().Parse(args).InvokeAsync()
241-
285+
242286

243287
/// Builds a `System.CommandLine.Command`.
244288
type CommandBuilder<'A, 'B, 'C, 'D, 'E, 'F, 'G, 'H, 'I, 'J, 'K, 'L, 'M, 'N, 'O, 'P, 'Output>(name: string) =
@@ -250,11 +294,17 @@ type CommandBuilder<'A, 'B, 'C, 'D, 'E, 'F, 'G, 'H, 'I, 'J, 'K, 'L, 'M, 'N, 'O,
250294
|> this.SetGeneralProperties spec
251295
|> this.SetActionHandler spec
252296

253-
/// Returns a Command with a handler that returns a Task.
297+
/// Executes a Command with a handler that returns int.
298+
member this.Run (spec: CommandSpec<'Inputs, int>) =
299+
this.CommandLineBuilder.Command
300+
|> this.SetGeneralProperties spec
301+
|> this.SetFuncHandlerSync spec
302+
303+
/// Executes a Command with a handler that returns a Task<unit> or Task<int>.
254304
member this.Run (spec: CommandSpec<'Inputs, Task<'ReturnValue>>) =
255305
Command(name)
256306
|> this.SetGeneralProperties spec
257-
|> this.SetFuncHandler spec
307+
|> this.SetFuncHandlerAsync spec
258308

259309

260310
/// Builds a `System.CommandLine.RootCommand` using computation expression syntax.

0 commit comments

Comments
 (0)