Skip to content

Commit 0c6c65d

Browse files
committed
Added validate and addValidator fns.
1 parent d9ab78c commit 0c6c65d

File tree

2 files changed

+75
-24
lines changed

2 files changed

+75
-24
lines changed

src/FSharp.SystemCommandLine/Inputs.fs

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,6 @@ type ActionContext =
1919
ParseResult: ParseResult
2020
CancellationToken: System.Threading.CancellationToken
2121
}
22-
static member Create(parseResult: ParseResult) =
23-
{
24-
ParseResult = parseResult
25-
CancellationToken = System.Threading.CancellationToken.None
26-
}
2722

2823
type ActionInputSource =
2924
| ParsedOption of Option
@@ -57,43 +52,43 @@ module Input =
5752
let option<'T> (name: string) =
5853
Option<'T>(name) |> ActionInput.OfOption
5954

60-
let editOption (edit: Option<'T> -> unit) (hi: ActionInput<'T>) =
61-
match hi.Source with
55+
let editOption (edit: Option<'T> -> unit) (input: ActionInput<'T>) =
56+
match input.Source with
6257
| ParsedOption o -> o :?> Option<'T> |> edit
6358
| _ -> ()
64-
hi
59+
input
6560

66-
let editArgument (edit: Argument<'T> -> unit) (hi: ActionInput<'T>) =
67-
match hi.Source with
61+
let editArgument (edit: Argument<'T> -> unit) (input: ActionInput<'T>) =
62+
match input.Source with
6863
| ParsedArgument a -> a :?> Argument<'T> |> edit
6964
| _ -> ()
70-
hi
65+
input
7166

72-
let aliases (aliases: string seq) (hi: ActionInput<'T>) =
73-
hi |> editOption (fun o -> aliases |> Seq.iter o.Aliases.Add)
67+
let aliases (aliases: string seq) (input: ActionInput<'T>) =
68+
input |> editOption (fun o -> aliases |> Seq.iter o.Aliases.Add)
7469

75-
let alias (alias: string) (hi: ActionInput<'T>) =
76-
hi |> editOption (fun o -> o.Aliases.Add alias)
70+
let alias (alias: string) (input: ActionInput<'T>) =
71+
input |> editOption (fun o -> o.Aliases.Add alias)
7772

78-
let desc (description: string) (hi: ActionInput<'T>) =
79-
hi
73+
let desc (description: string) (input: ActionInput<'T>) =
74+
input
8075
|> editOption (fun o -> o.Description <- description)
8176
|> editArgument (fun a -> a.Description <- description)
8277

83-
let defaultValue (defaultValue: 'T) (hi: ActionInput<'T>) =
84-
hi
78+
let defaultValue (defaultValue: 'T) (input: ActionInput<'T>) =
79+
input
8580
|> editOption (fun o -> o.DefaultValueFactory <- (fun _ -> defaultValue))
8681
|> editArgument (fun a -> a.DefaultValueFactory <- (fun _ -> defaultValue))
8782

8883
let def = defaultValue
8984

90-
let defFactory (defaultValueFactory: Parsing.ArgumentResult -> 'T) (hi: ActionInput<'T>) =
91-
hi
85+
let defFactory (defaultValueFactory: Parsing.ArgumentResult -> 'T) (input: ActionInput<'T>) =
86+
input
9287
|> editOption (fun o -> o.DefaultValueFactory <- defaultValueFactory)
9388
|> editArgument (fun a -> a.DefaultValueFactory <- defaultValueFactory)
9489

95-
let required (hi: ActionInput<'T>) =
96-
hi |> editOption (fun o -> o.Required <- true)
90+
let required (input: ActionInput<'T>) =
91+
input |> editOption (fun o -> o.Required <- true)
9792

9893
let optionMaybe<'T> (name: string) =
9994
let o = Option<'T option>(name, aliases = [||])
@@ -124,6 +119,31 @@ module Input =
124119
)
125120
ActionInput.OfArgument<'T option> a
126121

122+
let validate (validate: 'T -> Result<unit, string>) (input: ActionInput<'T>) =
123+
input
124+
|> editOption (fun o ->
125+
o.Validators.Add(fun res ->
126+
let value = res.GetValue<'T>(o.Name)
127+
match validate value with
128+
| Ok () -> ()
129+
| Error err -> res.AddError(err)
130+
)
131+
)
132+
|> editArgument (fun a ->
133+
a.Validators.Add(fun res ->
134+
let value = res.GetValue<'T>(a.Name)
135+
match validate value with
136+
| Ok () -> ()
137+
| Error err -> res.AddError(err)
138+
)
139+
)
140+
141+
let addValidator (validator: Parsing.SymbolResult -> unit) (input: ActionInput<'T>) =
142+
input
143+
|> editOption (fun o -> o.Validators.Add(validator))
144+
|> editArgument (fun a -> a.Validators.Add(validator))
145+
146+
127147
let ofOption (o: Option<'T>) =
128148
ActionInput.OfOption<'T> o
129149

src/Tests/SimpleAppTest.fs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,35 @@ let ``06 Token Replacer`` () =
114114
1 // failure
115115
)
116116
} =! 0
117-
117+
118+
[<Test>]
119+
let ``07 - Validators`` () =
120+
handlerCalled <- true // Set to true to avoid false negatives in the test
121+
let args = args "-w delete -s *"
122+
let cfg =
123+
commandLineConfiguration {
124+
description "Appends words together"
125+
inputs (
126+
option<string[]> "--word"
127+
|> alias "-w"
128+
|> desc "A list of words to be appended"
129+
|> required
130+
|> validate (fun words ->
131+
if words |> Array.contains "delete"
132+
then Error "Word 'delete' is not allowed."
133+
else Ok ()
134+
),
135+
136+
optionMaybe<string> "--separator"
137+
|> alias "-s"
138+
|> desc "A character that will separate the joined words."
139+
)
140+
141+
setAction (fun (words, separator) ->
142+
() // Should not be called due to validation failure
143+
)
144+
}
145+
146+
printfn $"{cfg.Error}"
147+
let result = cfg.Invoke(args)
148+
result =! 1 // Expecting a failure due to the separator validation

0 commit comments

Comments
 (0)