Skip to content

Commit

Permalink
Merge pull request #150 from mcon/or-spaced-attribute-to-tutorial
Browse files Browse the repository at this point in the history
`EqualsAssignmentOrSpaced` was broken with option types
  • Loading branch information
eiriktsarpalis authored Jun 8, 2020
2 parents 8ebd85d + 78566ea commit e120d5c
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 8 deletions.
20 changes: 12 additions & 8 deletions src/Argu/Parsers/Cli.fs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,15 @@ type CliParseState =
Reader : CliTokenReader
}

let private parseOptionalWithoutAssignment<'T> field state argInfo =
match state.Reader.GetNextToken true argInfo with
| UnrecognizedOrArgument tok ->
let argument = try Some(field.Parser tok :?> 'T) with _ -> None
match argument with Some _ -> state.Reader.MoveNext() | None -> ()
argument :> obj

| _ -> Option<'T>.None :> obj

/// parse the next command line argument and append to state
let rec private parseCommandLinePartial (state : CliParseState) (argInfo : UnionArgInfo) (aggregator : CliParseResultAggregator) =
state.Reader.BeginCliSegment()
Expand Down Expand Up @@ -365,7 +374,8 @@ let rec private parseCommandLinePartial (state : CliParseState) (argInfo : Union
let optArgument = existential.Accept { new IFunc<obj> with
member __.Invoke<'T> () =
match assignment with
| NoAssignment -> Option<'T>.None :> obj
| NoAssignment ->
parseOptionalWithoutAssignment<'T> field state argInfo
| Assignment(_,_,eqp) ->
let argument =
try field.Parser eqp
Expand All @@ -380,13 +390,7 @@ let rec private parseCommandLinePartial (state : CliParseState) (argInfo : Union
| OptionalParam(existential, field) ->
let optArgument = existential.Accept { new IFunc<obj> with
member __.Invoke<'T> () =
match state.Reader.GetNextToken true argInfo with
| UnrecognizedOrArgument tok ->
let argument = try Some(field.Parser tok :?> 'T) with _ -> None
match argument with Some _ -> state.Reader.MoveNext() | None -> ()
argument :> obj

| _ -> Option<'T>.None :> obj }
parseOptionalWithoutAssignment<'T> field state argInfo }

aggregator.AppendResult caseInfo name [| optArgument |]

Expand Down
7 changes: 7 additions & 0 deletions tests/Argu.Tests/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ module ``Argu Tests Main List`` =
| [<EqualsAssignment>] Env of key:string * value:string
| [<EqualsAssignment>] Dir of path:string
| [<EqualsAssignmentOrSpaced>] Flex_Equals_Assignment of string
| [<EqualsAssignmentOrSpaced>] Flex_Equals_Assignment_With_Option of string option
| [<ColonAssignmentOrSpaced>] Flex_Colon_Assignment of string
| [<First>] First_Parameter of string
| [<Last>] Last_Parameter of string
Expand Down Expand Up @@ -106,6 +107,7 @@ module ``Argu Tests Main List`` =
| Data _ -> "pass raw data in base64 format."
| Dir _ -> "Project directory to place the config & database in."
| Flex_Equals_Assignment _ -> "An equals assignment which can also be used with a space separator"
| Flex_Equals_Assignment_With_Option _ -> "Flex_Equals_Assignment but with optional parameter type"
| Flex_Colon_Assignment _ -> "A colon assignment which can also be used with a space separator"
| Log_Level _ -> "set the log level."
| Detach _ -> "detach daemon from console."
Expand Down Expand Up @@ -326,6 +328,11 @@ module ``Argu Tests Main List`` =
let ``Parse equals or space assignment with space`` () =
let result = parser.Parse([|"--flex-equals-assignment"; "../../my-relative-path"; "--dir==foo"|], ignoreMissing = true)
test <@ result.GetResult Flex_Equals_Assignment = "../../my-relative-path" @>

[<Fact>]
let ``Parse equals or space assignment with space and optional type`` () =
let result = parser.Parse([|"--flex-equals-assignment-with-option"; "../../my-relative-path"; "--dir==foo"|], ignoreMissing = true)
test <@ result.GetResult Flex_Equals_Assignment_With_Option = Some "../../my-relative-path" @>

[<Fact>]
let ``Parse colon or space assignment with colon`` () =
Expand Down

0 comments on commit e120d5c

Please sign in to comment.