mirror of
https://github.com/Smaug123/WoofWare.Myriad
synced 2025-10-08 05:28:39 +00:00
6284 lines
279 KiB
Forth
6284 lines
279 KiB
Forth
//------------------------------------------------------------------------------
|
|
// This code was generated by myriad.
|
|
// Changes to this file will be lost when the code is regenerated.
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace ArgParserHelpers
|
|
|
|
/// Helper types for arg parsing
|
|
module internal ArgParseHelpers_ConsumePlugin =
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
open ConsumePlugin
|
|
|
|
/// A partially-parsed BasicNoPositionals.
|
|
type internal BasicNoPositionals_InProgress =
|
|
{
|
|
mutable Bar : string option
|
|
mutable Baz : bool option
|
|
mutable Foo : int option
|
|
mutable Rest : ResizeArray<int>
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<BasicNoPositionals * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : int =
|
|
match this.Foo with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "foo")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : string =
|
|
match this.Bar with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "bar")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg2 : bool =
|
|
match this.Baz with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "baz")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg3 : int list = this.Rest |> Seq.toList
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
Foo = arg0
|
|
Bar = arg1
|
|
Baz = arg2
|
|
Rest = arg3
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : BasicNoPositionals_InProgress =
|
|
{
|
|
Bar = None
|
|
Baz = None
|
|
Foo = None
|
|
Rest = ResizeArray ()
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if System.String.Equals (key, sprintf "--%s" "rest", System.StringComparison.OrdinalIgnoreCase) then
|
|
value |> (fun x -> System.Int32.Parse x) |> (fun x -> x) |> this.Rest.Add
|
|
() |> Ok
|
|
else if System.String.Equals (key, sprintf "--%s" "foo", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Foo with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "foo")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Foo <- value |> (fun x -> System.Int32.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if System.String.Equals (key, sprintf "--%s" "baz", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Baz with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "baz")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Baz <- value |> (fun x -> System.Boolean.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if System.String.Equals (key, sprintf "--%s" "bar", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Bar with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "bar")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Bar <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool =
|
|
if System.String.Equals (key, sprintf "--%s" "baz", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Baz with
|
|
| Some _ ->
|
|
sprintf "Flag '%s' was supplied multiple times" (sprintf "--%s" "baz")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.Baz <- true |> Some
|
|
true
|
|
else
|
|
false
|
|
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed Basic.
|
|
type internal Basic_InProgress =
|
|
{
|
|
mutable Bar : string option
|
|
mutable Baz : bool option
|
|
mutable Foo : int option
|
|
mutable Rest : ResizeArray<string * int>
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<Basic * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : int =
|
|
match this.Foo with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "foo")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : string =
|
|
match this.Bar with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "bar")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg2 : bool =
|
|
match this.Baz with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "baz")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg3 : string list =
|
|
positionalConsumers.Add (sprintf "--%s" "rest")
|
|
|
|
positionals
|
|
|> Seq.map (fun x ->
|
|
match x with
|
|
| Choice1Of2 x ->
|
|
if not (false) && (fst x).StartsWith ("--", System.StringComparison.Ordinal) then
|
|
outOfPlacePositionals.Add (fst x)
|
|
x
|
|
else
|
|
x
|
|
| Choice2Of2 x -> x
|
|
)
|
|
|> Seq.map (fun (str, argNum_) -> str |> (fun x -> x), argNum_)
|
|
|> (fun x -> Seq.append this.Rest x)
|
|
|> Seq.sortBy snd
|
|
|> Seq.map fst
|
|
|> Seq.toList
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
Foo = arg0
|
|
Bar = arg1
|
|
Baz = arg2
|
|
Rest = arg3
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : Basic_InProgress =
|
|
{
|
|
Bar = None
|
|
Baz = None
|
|
Foo = None
|
|
Rest = ResizeArray ()
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if System.String.Equals (key, sprintf "--%s" "rest", System.StringComparison.OrdinalIgnoreCase) then
|
|
value |> (fun x -> x) |> (fun x -> x, argNum_) |> this.Rest.Add
|
|
() |> Ok
|
|
else if System.String.Equals (key, sprintf "--%s" "foo", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Foo with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "foo")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Foo <- value |> (fun x -> System.Int32.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if System.String.Equals (key, sprintf "--%s" "baz", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Baz with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "baz")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Baz <- value |> (fun x -> System.Boolean.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if System.String.Equals (key, sprintf "--%s" "bar", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Bar with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "bar")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Bar <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool =
|
|
if System.String.Equals (key, sprintf "--%s" "baz", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Baz with
|
|
| Some _ ->
|
|
sprintf "Flag '%s' was supplied multiple times" (sprintf "--%s" "baz")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.Baz <- true |> Some
|
|
true
|
|
else
|
|
false
|
|
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed BasicWithIntPositionals.
|
|
type internal BasicWithIntPositionals_InProgress =
|
|
{
|
|
mutable Bar : string option
|
|
mutable Baz : bool option
|
|
mutable Foo : int option
|
|
mutable Rest : ResizeArray<int * int>
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<BasicWithIntPositionals * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : int =
|
|
match this.Foo with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "foo")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : string =
|
|
match this.Bar with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "bar")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg2 : bool =
|
|
match this.Baz with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "baz")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg3 : int list =
|
|
positionalConsumers.Add (sprintf "--%s" "rest")
|
|
|
|
positionals
|
|
|> Seq.map (fun x ->
|
|
match x with
|
|
| Choice1Of2 x ->
|
|
if not (false) && (fst x).StartsWith ("--", System.StringComparison.Ordinal) then
|
|
outOfPlacePositionals.Add (fst x)
|
|
x
|
|
else
|
|
x
|
|
| Choice2Of2 x -> x
|
|
)
|
|
|> Seq.map (fun (str, argNum_) -> str |> (fun x -> System.Int32.Parse x), argNum_)
|
|
|> (fun x -> Seq.append this.Rest x)
|
|
|> Seq.sortBy snd
|
|
|> Seq.map fst
|
|
|> Seq.toList
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
Foo = arg0
|
|
Bar = arg1
|
|
Baz = arg2
|
|
Rest = arg3
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : BasicWithIntPositionals_InProgress =
|
|
{
|
|
Bar = None
|
|
Baz = None
|
|
Foo = None
|
|
Rest = ResizeArray ()
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if System.String.Equals (key, sprintf "--%s" "rest", System.StringComparison.OrdinalIgnoreCase) then
|
|
value
|
|
|> (fun x -> System.Int32.Parse x)
|
|
|> (fun x -> x, argNum_)
|
|
|> this.Rest.Add
|
|
|
|
() |> Ok
|
|
else if System.String.Equals (key, sprintf "--%s" "foo", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Foo with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "foo")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Foo <- value |> (fun x -> System.Int32.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if System.String.Equals (key, sprintf "--%s" "baz", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Baz with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "baz")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Baz <- value |> (fun x -> System.Boolean.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if System.String.Equals (key, sprintf "--%s" "bar", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Bar with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "bar")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Bar <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool =
|
|
if System.String.Equals (key, sprintf "--%s" "baz", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Baz with
|
|
| Some _ ->
|
|
sprintf "Flag '%s' was supplied multiple times" (sprintf "--%s" "baz")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.Baz <- true |> Some
|
|
true
|
|
else
|
|
false
|
|
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed LoadsOfTypes.
|
|
type internal LoadsOfTypes_InProgress =
|
|
{
|
|
mutable AnotherOptionalThing : int option
|
|
mutable Bar : string option
|
|
mutable Baz : bool option
|
|
mutable Foo : int option
|
|
mutable OptionalThing : bool option
|
|
mutable OptionalThingWithNoDefault : int option
|
|
mutable Positionals : ResizeArray<int * int>
|
|
mutable SomeDirectory : DirectoryInfo option
|
|
mutable SomeFile : FileInfo option
|
|
mutable SomeList : ResizeArray<DirectoryInfo>
|
|
mutable YetAnotherOptionalThing : string option
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<LoadsOfTypes * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : int =
|
|
match this.Foo with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "foo")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : string =
|
|
match this.Bar with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "bar")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg2 : bool =
|
|
match this.Baz with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "baz")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg3 : FileInfo =
|
|
match this.SomeFile with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "some-file")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg4 : DirectoryInfo =
|
|
match this.SomeDirectory with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "some-directory")
|
|
|
|
Unchecked.defaultof<_ >
|
|
|
|
let arg5 : DirectoryInfo list = this.SomeList |> Seq.toList
|
|
let arg6 : int option = this.OptionalThingWithNoDefault
|
|
|
|
let arg7 : int list =
|
|
positionalConsumers.Add (sprintf "--%s" "positionals")
|
|
|
|
positionals
|
|
|> Seq.map (fun x ->
|
|
match x with
|
|
| Choice1Of2 x ->
|
|
if not (false) && (fst x).StartsWith ("--", System.StringComparison.Ordinal) then
|
|
outOfPlacePositionals.Add (fst x)
|
|
x
|
|
else
|
|
x
|
|
| Choice2Of2 x -> x
|
|
)
|
|
|> Seq.map (fun (str, argNum_) -> str |> (fun x -> System.Int32.Parse x), argNum_)
|
|
|> (fun x -> Seq.append this.Positionals x)
|
|
|> Seq.sortBy snd
|
|
|> Seq.map fst
|
|
|> Seq.toList
|
|
|
|
let arg8 : Choice<bool, bool> =
|
|
match this.OptionalThing with
|
|
| Some result -> Choice1Of2 result
|
|
| None -> Choice2Of2 (LoadsOfTypes.DefaultOptionalThing ())
|
|
|
|
let arg9 : Choice<int, int> =
|
|
match this.AnotherOptionalThing with
|
|
| Some result -> Choice1Of2 result
|
|
| None -> Choice2Of2 (LoadsOfTypes.DefaultAnotherOptionalThing ())
|
|
|
|
let arg10 : Choice<string, string> =
|
|
match this.YetAnotherOptionalThing with
|
|
| Some result -> Choice1Of2 result
|
|
| None -> Choice2Of2 ("CONSUMEPLUGIN_THINGS" |> getEnvironmentVariable |> (fun x -> x))
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
Foo = arg0
|
|
Bar = arg1
|
|
Baz = arg2
|
|
SomeFile = arg3
|
|
SomeDirectory = arg4
|
|
SomeList = arg5
|
|
OptionalThingWithNoDefault = arg6
|
|
Positionals = arg7
|
|
OptionalThing = arg8
|
|
AnotherOptionalThing = arg9
|
|
YetAnotherOptionalThing = arg10
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : LoadsOfTypes_InProgress =
|
|
{
|
|
AnotherOptionalThing = None
|
|
Bar = None
|
|
Baz = None
|
|
Foo = None
|
|
OptionalThing = None
|
|
OptionalThingWithNoDefault = None
|
|
Positionals = ResizeArray ()
|
|
SomeDirectory = None
|
|
SomeFile = None
|
|
SomeList = ResizeArray ()
|
|
YetAnotherOptionalThing = None
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if
|
|
System.String.Equals (
|
|
key,
|
|
sprintf "--%s" "yet-another-optional-thing",
|
|
System.StringComparison.OrdinalIgnoreCase
|
|
)
|
|
then
|
|
match this.YetAnotherOptionalThing with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "yet-another-optional-thing")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.YetAnotherOptionalThing <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (key, sprintf "--%s" "some-list", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
value
|
|
|> (fun x -> System.IO.DirectoryInfo x)
|
|
|> (fun x -> x)
|
|
|> this.SomeList.Add
|
|
|
|
() |> Ok
|
|
else if
|
|
System.String.Equals (key, sprintf "--%s" "some-file", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.SomeFile with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "some-file")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.SomeFile <- value |> (fun x -> System.IO.FileInfo x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (key, sprintf "--%s" "some-directory", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.SomeDirectory with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "some-directory")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.SomeDirectory <- value |> (fun x -> System.IO.DirectoryInfo x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (key, sprintf "--%s" "positionals", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
value
|
|
|> (fun x -> System.Int32.Parse x)
|
|
|> (fun x -> x, argNum_)
|
|
|> this.Positionals.Add
|
|
|
|
() |> Ok
|
|
else if
|
|
System.String.Equals (
|
|
key,
|
|
sprintf "--%s" "optional-thing-with-no-default",
|
|
System.StringComparison.OrdinalIgnoreCase
|
|
)
|
|
then
|
|
match this.OptionalThingWithNoDefault with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "optional-thing-with-no-default")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.OptionalThingWithNoDefault <- value |> (fun x -> System.Int32.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (key, sprintf "--%s" "optional-thing", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.OptionalThing with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "optional-thing")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.OptionalThing <- value |> (fun x -> System.Boolean.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if System.String.Equals (key, sprintf "--%s" "foo", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Foo with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "foo")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Foo <- value |> (fun x -> System.Int32.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if System.String.Equals (key, sprintf "--%s" "baz", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Baz with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "baz")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Baz <- value |> (fun x -> System.Boolean.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if System.String.Equals (key, sprintf "--%s" "bar", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Bar with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "bar")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Bar <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (
|
|
key,
|
|
sprintf "--%s" "another-optional-thing",
|
|
System.StringComparison.OrdinalIgnoreCase
|
|
)
|
|
then
|
|
match this.AnotherOptionalThing with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "another-optional-thing")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.AnotherOptionalThing <- value |> (fun x -> System.Int32.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool =
|
|
if
|
|
System.String.Equals (key, sprintf "--%s" "optional-thing", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.OptionalThing with
|
|
| Some _ ->
|
|
sprintf "Flag '%s' was supplied multiple times" (sprintf "--%s" "optional-thing")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.OptionalThing <- true |> Some
|
|
true
|
|
else if System.String.Equals (key, sprintf "--%s" "baz", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Baz with
|
|
| Some _ ->
|
|
sprintf "Flag '%s' was supplied multiple times" (sprintf "--%s" "baz")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.Baz <- true |> Some
|
|
true
|
|
else
|
|
false
|
|
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed LoadsOfTypesNoPositionals.
|
|
type internal LoadsOfTypesNoPositionals_InProgress =
|
|
{
|
|
mutable AnotherOptionalThing : int option
|
|
mutable Bar : string option
|
|
mutable Baz : bool option
|
|
mutable Foo : int option
|
|
mutable OptionalThing : bool option
|
|
mutable OptionalThingWithNoDefault : int option
|
|
mutable SomeDirectory : DirectoryInfo option
|
|
mutable SomeFile : FileInfo option
|
|
mutable SomeList : ResizeArray<DirectoryInfo>
|
|
mutable YetAnotherOptionalThing : string option
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<LoadsOfTypesNoPositionals * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : int =
|
|
match this.Foo with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "foo")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : string =
|
|
match this.Bar with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "bar")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg2 : bool =
|
|
match this.Baz with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "baz")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg3 : FileInfo =
|
|
match this.SomeFile with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "some-file")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg4 : DirectoryInfo =
|
|
match this.SomeDirectory with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "some-directory")
|
|
|
|
Unchecked.defaultof<_ >
|
|
|
|
let arg5 : DirectoryInfo list = this.SomeList |> Seq.toList
|
|
let arg6 : int option = this.OptionalThingWithNoDefault
|
|
|
|
let arg7 : Choice<bool, bool> =
|
|
match this.OptionalThing with
|
|
| Some result -> Choice1Of2 result
|
|
| None -> Choice2Of2 (LoadsOfTypesNoPositionals.DefaultOptionalThing ())
|
|
|
|
let arg8 : Choice<int, int> =
|
|
match this.AnotherOptionalThing with
|
|
| Some result -> Choice1Of2 result
|
|
| None -> Choice2Of2 (LoadsOfTypesNoPositionals.DefaultAnotherOptionalThing ())
|
|
|
|
let arg9 : Choice<string, string> =
|
|
match this.YetAnotherOptionalThing with
|
|
| Some result -> Choice1Of2 result
|
|
| None -> Choice2Of2 ("CONSUMEPLUGIN_THINGS" |> getEnvironmentVariable |> (fun x -> x))
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
Foo = arg0
|
|
Bar = arg1
|
|
Baz = arg2
|
|
SomeFile = arg3
|
|
SomeDirectory = arg4
|
|
SomeList = arg5
|
|
OptionalThingWithNoDefault = arg6
|
|
OptionalThing = arg7
|
|
AnotherOptionalThing = arg8
|
|
YetAnotherOptionalThing = arg9
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : LoadsOfTypesNoPositionals_InProgress =
|
|
{
|
|
AnotherOptionalThing = None
|
|
Bar = None
|
|
Baz = None
|
|
Foo = None
|
|
OptionalThing = None
|
|
OptionalThingWithNoDefault = None
|
|
SomeDirectory = None
|
|
SomeFile = None
|
|
SomeList = ResizeArray ()
|
|
YetAnotherOptionalThing = None
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if
|
|
System.String.Equals (
|
|
key,
|
|
sprintf "--%s" "yet-another-optional-thing",
|
|
System.StringComparison.OrdinalIgnoreCase
|
|
)
|
|
then
|
|
match this.YetAnotherOptionalThing with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "yet-another-optional-thing")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.YetAnotherOptionalThing <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (key, sprintf "--%s" "some-list", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
value
|
|
|> (fun x -> System.IO.DirectoryInfo x)
|
|
|> (fun x -> x)
|
|
|> this.SomeList.Add
|
|
|
|
() |> Ok
|
|
else if
|
|
System.String.Equals (key, sprintf "--%s" "some-file", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.SomeFile with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "some-file")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.SomeFile <- value |> (fun x -> System.IO.FileInfo x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (key, sprintf "--%s" "some-directory", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.SomeDirectory with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "some-directory")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.SomeDirectory <- value |> (fun x -> System.IO.DirectoryInfo x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (
|
|
key,
|
|
sprintf "--%s" "optional-thing-with-no-default",
|
|
System.StringComparison.OrdinalIgnoreCase
|
|
)
|
|
then
|
|
match this.OptionalThingWithNoDefault with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "optional-thing-with-no-default")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.OptionalThingWithNoDefault <- value |> (fun x -> System.Int32.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (key, sprintf "--%s" "optional-thing", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.OptionalThing with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "optional-thing")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.OptionalThing <- value |> (fun x -> System.Boolean.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if System.String.Equals (key, sprintf "--%s" "foo", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Foo with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "foo")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Foo <- value |> (fun x -> System.Int32.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if System.String.Equals (key, sprintf "--%s" "baz", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Baz with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "baz")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Baz <- value |> (fun x -> System.Boolean.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if System.String.Equals (key, sprintf "--%s" "bar", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Bar with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "bar")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Bar <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (
|
|
key,
|
|
sprintf "--%s" "another-optional-thing",
|
|
System.StringComparison.OrdinalIgnoreCase
|
|
)
|
|
then
|
|
match this.AnotherOptionalThing with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "another-optional-thing")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.AnotherOptionalThing <- value |> (fun x -> System.Int32.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool =
|
|
if
|
|
System.String.Equals (key, sprintf "--%s" "optional-thing", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.OptionalThing with
|
|
| Some _ ->
|
|
sprintf "Flag '%s' was supplied multiple times" (sprintf "--%s" "optional-thing")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.OptionalThing <- true |> Some
|
|
true
|
|
else if System.String.Equals (key, sprintf "--%s" "baz", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Baz with
|
|
| Some _ ->
|
|
sprintf "Flag '%s' was supplied multiple times" (sprintf "--%s" "baz")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.Baz <- true |> Some
|
|
true
|
|
else
|
|
false
|
|
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed DatesAndTimes.
|
|
type internal DatesAndTimes_InProgress =
|
|
{
|
|
mutable Exact : TimeSpan option
|
|
mutable Invariant : TimeSpan option
|
|
mutable InvariantExact : TimeSpan option
|
|
mutable Plain : TimeSpan option
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<DatesAndTimes * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : TimeSpan =
|
|
match this.Plain with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "plain")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : TimeSpan =
|
|
match this.Invariant with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "invariant")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg2 : TimeSpan =
|
|
match this.Exact with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "exact")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg3 : TimeSpan =
|
|
match this.InvariantExact with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "invariant-exact")
|
|
|
|
Unchecked.defaultof<_ >
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
Plain = arg0
|
|
Invariant = arg1
|
|
Exact = arg2
|
|
InvariantExact = arg3
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : DatesAndTimes_InProgress =
|
|
{
|
|
Exact = None
|
|
Invariant = None
|
|
InvariantExact = None
|
|
Plain = None
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if System.String.Equals (key, sprintf "--%s" "plain", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Plain with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "plain")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Plain <- value |> (fun x -> System.TimeSpan.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (key, sprintf "--%s" "invariant-exact", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.InvariantExact with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "invariant-exact")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.InvariantExact <-
|
|
value
|
|
|> (fun x ->
|
|
System.TimeSpan.ParseExact (
|
|
x,
|
|
@"hh\:mm\:ss",
|
|
System.Globalization.CultureInfo.InvariantCulture
|
|
)
|
|
)
|
|
|> Some
|
|
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (key, sprintf "--%s" "invariant", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.Invariant with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "invariant")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Invariant <-
|
|
value
|
|
|> (fun x -> System.TimeSpan.Parse (x, System.Globalization.CultureInfo.InvariantCulture))
|
|
|> Some
|
|
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if System.String.Equals (key, sprintf "--%s" "exact", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Exact with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "exact")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Exact <-
|
|
value
|
|
|> (fun x ->
|
|
System.TimeSpan.ParseExact (
|
|
x,
|
|
@"hh\:mm\:ss",
|
|
System.Globalization.CultureInfo.CurrentCulture
|
|
)
|
|
)
|
|
|> Some
|
|
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool = false
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed ChildRecord.
|
|
type internal ChildRecord_InProgress =
|
|
{
|
|
mutable Thing1 : int option
|
|
mutable Thing2 : string option
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<ChildRecord * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : int =
|
|
match this.Thing1 with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "thing1")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : string =
|
|
match this.Thing2 with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "thing2")
|
|
Unchecked.defaultof<_>
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
Thing1 = arg0
|
|
Thing2 = arg1
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : ChildRecord_InProgress =
|
|
{
|
|
Thing1 = None
|
|
Thing2 = None
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if System.String.Equals (key, sprintf "--%s" "thing2", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Thing2 with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "thing2")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Thing2 <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if System.String.Equals (key, sprintf "--%s" "thing1", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Thing1 with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "thing1")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Thing1 <- value |> (fun x -> System.Int32.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool = false
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed ParentRecord.
|
|
type internal ParentRecord_InProgress =
|
|
{
|
|
mutable AndAnother : bool option
|
|
mutable Child : ChildRecord_InProgress
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<ParentRecord * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : ChildRecord =
|
|
match this.Child.Assemble_ getEnvironmentVariable positionals with
|
|
| Ok (result, consumedPositional) ->
|
|
match consumedPositional with
|
|
| None -> ()
|
|
| Some positionalConsumer -> positionalConsumers.Add positionalConsumer
|
|
|
|
result
|
|
| Error err ->
|
|
errors.AddRange err
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : bool =
|
|
match this.AndAnother with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "and-another")
|
|
Unchecked.defaultof<_>
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
Child = arg0
|
|
AndAnother = arg1
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : ParentRecord_InProgress =
|
|
{
|
|
AndAnother = None
|
|
Child = ChildRecord_InProgress._Empty ()
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if System.String.Equals (key, sprintf "--%s" "and-another", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.AndAnother with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "and-another")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.AndAnother <- value |> (fun x -> System.Boolean.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
/// Passes the key-value pair to any child records, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueRecord_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
let errors : ResizeArray<string> = ResizeArray ()
|
|
|
|
match this.Child.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error e -> Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None ->
|
|
match this.ProcessKeyValueRecord_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error errorFromRecord -> Error errorFromRecord
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool =
|
|
if System.String.Equals (key, sprintf "--%s" "and-another", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.AndAnother with
|
|
| Some _ ->
|
|
sprintf "Flag '%s' was supplied multiple times" (sprintf "--%s" "and-another")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.AndAnother <- true |> Some
|
|
true
|
|
else
|
|
false
|
|
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed ChildRecordWithPositional.
|
|
type internal ChildRecordWithPositional_InProgress =
|
|
{
|
|
mutable Thing1 : int option
|
|
mutable Thing2 : ResizeArray<Uri * int>
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<ChildRecordWithPositional * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : int =
|
|
match this.Thing1 with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "thing1")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : Uri list =
|
|
positionalConsumers.Add (sprintf "--%s" "thing2")
|
|
|
|
positionals
|
|
|> Seq.map (fun x ->
|
|
match x with
|
|
| Choice1Of2 x ->
|
|
if not (false) && (fst x).StartsWith ("--", System.StringComparison.Ordinal) then
|
|
outOfPlacePositionals.Add (fst x)
|
|
x
|
|
else
|
|
x
|
|
| Choice2Of2 x -> x
|
|
)
|
|
|> Seq.map (fun (str, argNum_) -> str |> (fun x -> System.Uri x), argNum_)
|
|
|> (fun x -> Seq.append this.Thing2 x)
|
|
|> Seq.sortBy snd
|
|
|> Seq.map fst
|
|
|> Seq.toList
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
Thing1 = arg0
|
|
Thing2 = arg1
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : ChildRecordWithPositional_InProgress =
|
|
{
|
|
Thing1 = None
|
|
Thing2 = ResizeArray ()
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if System.String.Equals (key, sprintf "--%s" "thing2", System.StringComparison.OrdinalIgnoreCase) then
|
|
value |> (fun x -> System.Uri x) |> (fun x -> x, argNum_) |> this.Thing2.Add
|
|
() |> Ok
|
|
else if System.String.Equals (key, sprintf "--%s" "thing1", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.Thing1 with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "thing1")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.Thing1 <- value |> (fun x -> System.Int32.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool = false
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed ParentRecordChildPos.
|
|
type internal ParentRecordChildPos_InProgress =
|
|
{
|
|
mutable AndAnother : bool option
|
|
mutable Child : ChildRecordWithPositional_InProgress
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<ParentRecordChildPos * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : ChildRecordWithPositional =
|
|
match this.Child.Assemble_ getEnvironmentVariable positionals with
|
|
| Ok (result, consumedPositional) ->
|
|
match consumedPositional with
|
|
| None -> ()
|
|
| Some positionalConsumer -> positionalConsumers.Add positionalConsumer
|
|
|
|
result
|
|
| Error err ->
|
|
errors.AddRange err
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : bool =
|
|
match this.AndAnother with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "and-another")
|
|
Unchecked.defaultof<_>
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
Child = arg0
|
|
AndAnother = arg1
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : ParentRecordChildPos_InProgress =
|
|
{
|
|
AndAnother = None
|
|
Child = ChildRecordWithPositional_InProgress._Empty ()
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if System.String.Equals (key, sprintf "--%s" "and-another", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.AndAnother with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "and-another")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.AndAnother <- value |> (fun x -> System.Boolean.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
/// Passes the key-value pair to any child records, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueRecord_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
let errors : ResizeArray<string> = ResizeArray ()
|
|
|
|
match this.Child.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error e -> Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None ->
|
|
match this.ProcessKeyValueRecord_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error errorFromRecord -> Error errorFromRecord
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool =
|
|
if System.String.Equals (key, sprintf "--%s" "and-another", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.AndAnother with
|
|
| Some _ ->
|
|
sprintf "Flag '%s' was supplied multiple times" (sprintf "--%s" "and-another")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.AndAnother <- true |> Some
|
|
true
|
|
else
|
|
false
|
|
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed ParentRecordSelfPos.
|
|
type internal ParentRecordSelfPos_InProgress =
|
|
{
|
|
mutable AndAnother : ResizeArray<bool * int>
|
|
mutable Child : ChildRecord_InProgress
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<ParentRecordSelfPos * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : ChildRecord =
|
|
match this.Child.Assemble_ getEnvironmentVariable positionals with
|
|
| Ok (result, consumedPositional) ->
|
|
match consumedPositional with
|
|
| None -> ()
|
|
| Some positionalConsumer -> positionalConsumers.Add positionalConsumer
|
|
|
|
result
|
|
| Error err ->
|
|
errors.AddRange err
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : bool list =
|
|
positionalConsumers.Add (sprintf "--%s" "and-another")
|
|
|
|
positionals
|
|
|> Seq.map (fun x ->
|
|
match x with
|
|
| Choice1Of2 x ->
|
|
if not (false) && (fst x).StartsWith ("--", System.StringComparison.Ordinal) then
|
|
outOfPlacePositionals.Add (fst x)
|
|
x
|
|
else
|
|
x
|
|
| Choice2Of2 x -> x
|
|
)
|
|
|> Seq.map (fun (str, argNum_) -> str |> (fun x -> System.Boolean.Parse x), argNum_)
|
|
|> (fun x -> Seq.append this.AndAnother x)
|
|
|> Seq.sortBy snd
|
|
|> Seq.map fst
|
|
|> Seq.toList
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
Child = arg0
|
|
AndAnother = arg1
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : ParentRecordSelfPos_InProgress =
|
|
{
|
|
AndAnother = ResizeArray ()
|
|
Child = ChildRecord_InProgress._Empty ()
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if System.String.Equals (key, sprintf "--%s" "and-another", System.StringComparison.OrdinalIgnoreCase) then
|
|
value
|
|
|> (fun x -> System.Boolean.Parse x)
|
|
|> (fun x -> x, argNum_)
|
|
|> this.AndAnother.Add
|
|
|
|
() |> Ok
|
|
else
|
|
Error None
|
|
|
|
/// Passes the key-value pair to any child records, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueRecord_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
let errors : ResizeArray<string> = ResizeArray ()
|
|
|
|
match this.Child.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error e -> Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None ->
|
|
match this.ProcessKeyValueRecord_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error errorFromRecord -> Error errorFromRecord
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool = false
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed ChoicePositionals.
|
|
type internal ChoicePositionals_InProgress =
|
|
{
|
|
mutable Args : ResizeArray<string * int>
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<ChoicePositionals * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : Choice<string, string> list =
|
|
positionalConsumers.Add (sprintf "--%s" "args")
|
|
|
|
positionals
|
|
|> List.map (fun x ->
|
|
match x with
|
|
| Choice1Of2 (x, argPos) -> (fun x -> x) x |> Choice1Of2
|
|
| Choice2Of2 (x, argPos) -> (fun x -> x) x |> Choice2Of2
|
|
)
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
Args = arg0
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : ChoicePositionals_InProgress =
|
|
{
|
|
Args = ResizeArray ()
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if System.String.Equals (key, sprintf "--%s" "args", System.StringComparison.OrdinalIgnoreCase) then
|
|
value |> (fun x -> x) |> (fun x -> x, argNum_) |> this.Args.Add
|
|
() |> Ok
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool = false
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed ContainsBoolEnvVar.
|
|
type internal ContainsBoolEnvVar_InProgress =
|
|
{
|
|
mutable BoolVar : bool option
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<ContainsBoolEnvVar * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : Choice<bool, bool> =
|
|
match this.BoolVar with
|
|
| Some result -> Choice1Of2 result
|
|
| None ->
|
|
Choice2Of2 (
|
|
"CONSUMEPLUGIN_THINGS"
|
|
|> getEnvironmentVariable
|
|
|> (fun x ->
|
|
if System.String.Equals (x, "1", System.StringComparison.OrdinalIgnoreCase) then
|
|
true
|
|
else if System.String.Equals (x, "0", System.StringComparison.OrdinalIgnoreCase) then
|
|
false
|
|
else
|
|
x |> (fun x -> System.Boolean.Parse x)
|
|
)
|
|
)
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
BoolVar = arg0
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : ContainsBoolEnvVar_InProgress =
|
|
{
|
|
BoolVar = None
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if System.String.Equals (key, sprintf "--%s" "bool-var", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.BoolVar with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "bool-var")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.BoolVar <- value |> (fun x -> System.Boolean.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool =
|
|
if System.String.Equals (key, sprintf "--%s" "bool-var", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.BoolVar with
|
|
| Some _ ->
|
|
sprintf "Flag '%s' was supplied multiple times" (sprintf "--%s" "bool-var")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.BoolVar <- true |> Some
|
|
true
|
|
else
|
|
false
|
|
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed WithFlagDu.
|
|
type internal WithFlagDu_InProgress =
|
|
{
|
|
mutable DryRun : DryRunMode option
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<WithFlagDu * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : DryRunMode =
|
|
match this.DryRun with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "dry-run")
|
|
Unchecked.defaultof<_>
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
DryRun = arg0
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : WithFlagDu_InProgress =
|
|
{
|
|
DryRun = None
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if System.String.Equals (key, sprintf "--%s" "dry-run", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.DryRun with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "dry-run")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.DryRun <-
|
|
value
|
|
|> (fun x ->
|
|
if System.Boolean.Parse x = Consts.FALSE then
|
|
DryRunMode.Wet
|
|
else
|
|
DryRunMode.Dry
|
|
)
|
|
|> Some
|
|
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool =
|
|
if System.String.Equals (key, sprintf "--%s" "dry-run", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.DryRun with
|
|
| Some _ ->
|
|
sprintf "Flag '%s' was supplied multiple times" (sprintf "--%s" "dry-run")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.DryRun <-
|
|
if true = Consts.FALSE then
|
|
DryRunMode.Wet
|
|
else
|
|
DryRunMode.Dry
|
|
|> Some
|
|
|
|
true
|
|
else
|
|
false
|
|
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed ContainsFlagEnvVar.
|
|
type internal ContainsFlagEnvVar_InProgress =
|
|
{
|
|
mutable DryRun : DryRunMode option
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<ContainsFlagEnvVar * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : Choice<DryRunMode, DryRunMode> =
|
|
match this.DryRun with
|
|
| Some result -> Choice1Of2 result
|
|
| None ->
|
|
Choice2Of2 (
|
|
"CONSUMEPLUGIN_THINGS"
|
|
|> getEnvironmentVariable
|
|
|> (fun x ->
|
|
if System.String.Equals (x, "1", System.StringComparison.OrdinalIgnoreCase) then
|
|
if true = Consts.FALSE then
|
|
DryRunMode.Wet
|
|
else
|
|
DryRunMode.Dry
|
|
else if System.String.Equals (x, "0", System.StringComparison.OrdinalIgnoreCase) then
|
|
if false = Consts.FALSE then
|
|
DryRunMode.Wet
|
|
else
|
|
DryRunMode.Dry
|
|
else
|
|
x
|
|
|> (fun x ->
|
|
if System.Boolean.Parse x = Consts.FALSE then
|
|
DryRunMode.Wet
|
|
else
|
|
DryRunMode.Dry
|
|
)
|
|
)
|
|
)
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
DryRun = arg0
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : ContainsFlagEnvVar_InProgress =
|
|
{
|
|
DryRun = None
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if System.String.Equals (key, sprintf "--%s" "dry-run", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.DryRun with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "dry-run")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.DryRun <-
|
|
value
|
|
|> (fun x ->
|
|
if System.Boolean.Parse x = Consts.FALSE then
|
|
DryRunMode.Wet
|
|
else
|
|
DryRunMode.Dry
|
|
)
|
|
|> Some
|
|
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool =
|
|
if System.String.Equals (key, sprintf "--%s" "dry-run", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.DryRun with
|
|
| Some _ ->
|
|
sprintf "Flag '%s' was supplied multiple times" (sprintf "--%s" "dry-run")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.DryRun <-
|
|
if true = Consts.FALSE then
|
|
DryRunMode.Wet
|
|
else
|
|
DryRunMode.Dry
|
|
|> Some
|
|
|
|
true
|
|
else
|
|
false
|
|
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed ContainsFlagDefaultValue.
|
|
type internal ContainsFlagDefaultValue_InProgress =
|
|
{
|
|
mutable DryRun : DryRunMode option
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<ContainsFlagDefaultValue * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : Choice<DryRunMode, DryRunMode> =
|
|
match this.DryRun with
|
|
| Some result -> Choice1Of2 result
|
|
| None -> Choice2Of2 (ContainsFlagDefaultValue.DefaultDryRun ())
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
DryRun = arg0
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : ContainsFlagDefaultValue_InProgress =
|
|
{
|
|
DryRun = None
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if System.String.Equals (key, sprintf "--%s" "dry-run", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.DryRun with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "dry-run")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.DryRun <-
|
|
value
|
|
|> (fun x ->
|
|
if System.Boolean.Parse x = Consts.FALSE then
|
|
DryRunMode.Wet
|
|
else
|
|
DryRunMode.Dry
|
|
)
|
|
|> Some
|
|
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool =
|
|
if System.String.Equals (key, sprintf "--%s" "dry-run", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.DryRun with
|
|
| Some _ ->
|
|
sprintf "Flag '%s' was supplied multiple times" (sprintf "--%s" "dry-run")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.DryRun <-
|
|
if true = Consts.FALSE then
|
|
DryRunMode.Wet
|
|
else
|
|
DryRunMode.Dry
|
|
|> Some
|
|
|
|
true
|
|
else
|
|
false
|
|
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed ManyLongForms.
|
|
type internal ManyLongForms_InProgress =
|
|
{
|
|
mutable DoTheThing : string option
|
|
mutable SomeFlag : bool option
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<ManyLongForms * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : string =
|
|
match this.DoTheThing with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "do-something-else")
|
|
|
|
Unchecked.defaultof<_ >
|
|
|
|
let arg1 : bool =
|
|
match this.SomeFlag with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "turn-it-on")
|
|
Unchecked.defaultof<_>
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
DoTheThing = arg0
|
|
SomeFlag = arg1
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : ManyLongForms_InProgress =
|
|
{
|
|
DoTheThing = None
|
|
SomeFlag = None
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if
|
|
System.String.Equals (key, sprintf "--%s" "dont-turn-it-off", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.SomeFlag with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s / --%s" "turn-it-on" "dont-turn-it-off")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.SomeFlag <- value |> (fun x -> System.Boolean.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (key, sprintf "--%s" "turn-it-on", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.SomeFlag with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s / --%s" "turn-it-on" "dont-turn-it-off")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.SomeFlag <- value |> (fun x -> System.Boolean.Parse x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (key, sprintf "--%s" "anotherarg", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.DoTheThing with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s / --%s" "do-something-else" "anotherarg")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.DoTheThing <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else if
|
|
System.String.Equals (
|
|
key,
|
|
sprintf "--%s" "do-something-else",
|
|
System.StringComparison.OrdinalIgnoreCase
|
|
)
|
|
then
|
|
match this.DoTheThing with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s / --%s" "do-something-else" "anotherarg")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.DoTheThing <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool =
|
|
if
|
|
System.String.Equals (key, sprintf "--%s" "dont-turn-it-off", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.SomeFlag with
|
|
| Some _ ->
|
|
sprintf
|
|
"Flag '%s' was supplied multiple times"
|
|
(sprintf "--%s / --%s" "turn-it-on" "dont-turn-it-off")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.SomeFlag <- true |> Some
|
|
true
|
|
else if
|
|
System.String.Equals (key, sprintf "--%s" "turn-it-on", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
match this.SomeFlag with
|
|
| Some _ ->
|
|
sprintf
|
|
"Flag '%s' was supplied multiple times"
|
|
(sprintf "--%s / --%s" "turn-it-on" "dont-turn-it-off")
|
|
|> errors_.Add
|
|
|
|
true
|
|
| None ->
|
|
this.SomeFlag <- true |> Some
|
|
true
|
|
else
|
|
false
|
|
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed FlagsIntoPositionalArgs.
|
|
type internal FlagsIntoPositionalArgs_InProgress =
|
|
{
|
|
mutable A : string option
|
|
mutable GrabEverything : ResizeArray<string * int>
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<FlagsIntoPositionalArgs * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : string =
|
|
match this.A with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "a")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : string list =
|
|
positionalConsumers.Add (sprintf "--%s" "grab-everything")
|
|
|
|
positionals
|
|
|> Seq.map (fun x ->
|
|
match x with
|
|
| Choice1Of2 x ->
|
|
if not (true) && (fst x).StartsWith ("--", System.StringComparison.Ordinal) then
|
|
outOfPlacePositionals.Add (fst x)
|
|
x
|
|
else
|
|
x
|
|
| Choice2Of2 x -> x
|
|
)
|
|
|> Seq.map (fun (str, argNum_) -> str |> (fun x -> x), argNum_)
|
|
|> (fun x -> Seq.append this.GrabEverything x)
|
|
|> Seq.sortBy snd
|
|
|> Seq.map fst
|
|
|> Seq.toList
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
A = arg0
|
|
GrabEverything = arg1
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : FlagsIntoPositionalArgs_InProgress =
|
|
{
|
|
A = None
|
|
GrabEverything = ResizeArray ()
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if
|
|
System.String.Equals (key, sprintf "--%s" "grab-everything", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
value |> (fun x -> x) |> (fun x -> x, argNum_) |> this.GrabEverything.Add
|
|
() |> Ok
|
|
else if System.String.Equals (key, sprintf "--%s" "a", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.A with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "a")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.A <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool = false
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed FlagsIntoPositionalArgsChoice.
|
|
type internal FlagsIntoPositionalArgsChoice_InProgress =
|
|
{
|
|
mutable A : string option
|
|
mutable GrabEverything : ResizeArray<string * int>
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<FlagsIntoPositionalArgsChoice * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : string =
|
|
match this.A with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "a")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : Choice<string, string> list =
|
|
positionalConsumers.Add (sprintf "--%s" "grab-everything")
|
|
|
|
positionals
|
|
|> List.map (fun x ->
|
|
match x with
|
|
| Choice1Of2 (x, argPos) -> (fun x -> x) x |> Choice1Of2
|
|
| Choice2Of2 (x, argPos) -> (fun x -> x) x |> Choice2Of2
|
|
)
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
A = arg0
|
|
GrabEverything = arg1
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : FlagsIntoPositionalArgsChoice_InProgress =
|
|
{
|
|
A = None
|
|
GrabEverything = ResizeArray ()
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if
|
|
System.String.Equals (key, sprintf "--%s" "grab-everything", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
value |> (fun x -> x) |> (fun x -> x, argNum_) |> this.GrabEverything.Add
|
|
() |> Ok
|
|
else if System.String.Equals (key, sprintf "--%s" "a", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.A with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "a")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.A <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool = false
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed FlagsIntoPositionalArgsInt.
|
|
type internal FlagsIntoPositionalArgsInt_InProgress =
|
|
{
|
|
mutable A : string option
|
|
mutable GrabEverything : ResizeArray<int * int>
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<FlagsIntoPositionalArgsInt * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : string =
|
|
match this.A with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "a")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : int list =
|
|
positionalConsumers.Add (sprintf "--%s" "grab-everything")
|
|
|
|
positionals
|
|
|> Seq.map (fun x ->
|
|
match x with
|
|
| Choice1Of2 x ->
|
|
if not (true) && (fst x).StartsWith ("--", System.StringComparison.Ordinal) then
|
|
outOfPlacePositionals.Add (fst x)
|
|
x
|
|
else
|
|
x
|
|
| Choice2Of2 x -> x
|
|
)
|
|
|> Seq.map (fun (str, argNum_) -> str |> (fun x -> System.Int32.Parse x), argNum_)
|
|
|> (fun x -> Seq.append this.GrabEverything x)
|
|
|> Seq.sortBy snd
|
|
|> Seq.map fst
|
|
|> Seq.toList
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
A = arg0
|
|
GrabEverything = arg1
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : FlagsIntoPositionalArgsInt_InProgress =
|
|
{
|
|
A = None
|
|
GrabEverything = ResizeArray ()
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if
|
|
System.String.Equals (key, sprintf "--%s" "grab-everything", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
value
|
|
|> (fun x -> System.Int32.Parse x)
|
|
|> (fun x -> x, argNum_)
|
|
|> this.GrabEverything.Add
|
|
|
|
() |> Ok
|
|
else if System.String.Equals (key, sprintf "--%s" "a", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.A with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "a")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.A <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool = false
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed FlagsIntoPositionalArgsIntChoice.
|
|
type internal FlagsIntoPositionalArgsIntChoice_InProgress =
|
|
{
|
|
mutable A : string option
|
|
mutable GrabEverything : ResizeArray<int * int>
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<FlagsIntoPositionalArgsIntChoice * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : string =
|
|
match this.A with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "a")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : Choice<int, int> list =
|
|
positionalConsumers.Add (sprintf "--%s" "grab-everything")
|
|
|
|
positionals
|
|
|> List.map (fun x ->
|
|
match x with
|
|
| Choice1Of2 (x, argPos) -> (fun x -> System.Int32.Parse x) x |> Choice1Of2
|
|
| Choice2Of2 (x, argPos) -> (fun x -> System.Int32.Parse x) x |> Choice2Of2
|
|
)
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
A = arg0
|
|
GrabEverything = arg1
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : FlagsIntoPositionalArgsIntChoice_InProgress =
|
|
{
|
|
A = None
|
|
GrabEverything = ResizeArray ()
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if
|
|
System.String.Equals (key, sprintf "--%s" "grab-everything", System.StringComparison.OrdinalIgnoreCase)
|
|
then
|
|
value
|
|
|> (fun x -> System.Int32.Parse x)
|
|
|> (fun x -> x, argNum_)
|
|
|> this.GrabEverything.Add
|
|
|
|
() |> Ok
|
|
else if System.String.Equals (key, sprintf "--%s" "a", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.A with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "a")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.A <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool = false
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed FlagsIntoPositionalArgs'.
|
|
type internal FlagsIntoPositionalArgs'_InProgress =
|
|
{
|
|
mutable A : string option
|
|
mutable DontGrabEverything : ResizeArray<string * int>
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<FlagsIntoPositionalArgs' * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : string =
|
|
match this.A with
|
|
| Some result -> result
|
|
| None ->
|
|
errors.Add (sprintf "Required argument '--%s' received no value" "a")
|
|
Unchecked.defaultof<_>
|
|
|
|
let arg1 : string list =
|
|
positionalConsumers.Add (sprintf "--%s" "dont-grab-everything")
|
|
|
|
positionals
|
|
|> Seq.map (fun x ->
|
|
match x with
|
|
| Choice1Of2 x ->
|
|
if not (false) && (fst x).StartsWith ("--", System.StringComparison.Ordinal) then
|
|
outOfPlacePositionals.Add (fst x)
|
|
x
|
|
else
|
|
x
|
|
| Choice2Of2 x -> x
|
|
)
|
|
|> Seq.map (fun (str, argNum_) -> str |> (fun x -> x), argNum_)
|
|
|> (fun x -> Seq.append this.DontGrabEverything x)
|
|
|> Seq.sortBy snd
|
|
|> Seq.map fst
|
|
|> Seq.toList
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
A = arg0
|
|
DontGrabEverything = arg1
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : FlagsIntoPositionalArgs'_InProgress =
|
|
{
|
|
A = None
|
|
DontGrabEverything = ResizeArray ()
|
|
}
|
|
|
|
/// Processes the key-value pair, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueSelf_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
if
|
|
System.String.Equals (
|
|
key,
|
|
sprintf "--%s" "dont-grab-everything",
|
|
System.StringComparison.OrdinalIgnoreCase
|
|
)
|
|
then
|
|
value |> (fun x -> x) |> (fun x -> x, argNum_) |> this.DontGrabEverything.Add
|
|
() |> Ok
|
|
else if System.String.Equals (key, sprintf "--%s" "a", System.StringComparison.OrdinalIgnoreCase) then
|
|
match this.A with
|
|
| Some x ->
|
|
sprintf
|
|
"Argument '%s' was supplied multiple times: %s and %s"
|
|
(sprintf "--%s" "a")
|
|
(x.ToString ())
|
|
(value.ToString ())
|
|
|> errors_.Add
|
|
|
|
Ok ()
|
|
| None ->
|
|
try
|
|
this.A <- value |> (fun x -> x) |> Some
|
|
Ok ()
|
|
with _ as exc ->
|
|
exc.Message |> Some |> Error
|
|
else
|
|
Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueSelf_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error None -> Error None
|
|
| Error (Some errorFromLeaf) -> Error (Some errorFromLeaf)
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool = false
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
|
|
/// A partially-parsed PassThru.
|
|
type internal PassThru_InProgress =
|
|
{
|
|
mutable A : ParentRecordChildPos_InProgress
|
|
}
|
|
|
|
/// Freeze this in-progress type. On success, returns the frozen type and the arg (if any) which consumed the input positional args.
|
|
member this.Assemble_
|
|
(getEnvironmentVariable : string -> string)
|
|
(positionals : Choice<string * int, string * int> list)
|
|
: Result<PassThru * string option, string list>
|
|
=
|
|
let errors = ResizeArray<string> ()
|
|
let positionalConsumers = ResizeArray<string> ()
|
|
let outOfPlacePositionals : ResizeArray<string> = ResizeArray ()
|
|
|
|
let arg0 : ParentRecordChildPos =
|
|
match this.A.Assemble_ getEnvironmentVariable positionals with
|
|
| Ok (result, consumedPositional) ->
|
|
match consumedPositional with
|
|
| None -> ()
|
|
| Some positionalConsumer -> positionalConsumers.Add positionalConsumer
|
|
|
|
result
|
|
| Error err ->
|
|
errors.AddRange err
|
|
Unchecked.defaultof<_>
|
|
|
|
if positionalConsumers.Count <= 1 then
|
|
if outOfPlacePositionals.Count > 0 then
|
|
outOfPlacePositionals
|
|
|> String.concat " "
|
|
|> (fun x ->
|
|
if 0 = outOfPlacePositionals.Count then
|
|
"Unmatched args which look like they are meant to be flags. " + x
|
|
else
|
|
sprintf
|
|
"Unmatched args which look like they are meant to be flags. If you intended them as positional args, explicitly pass them with the `%s=` syntax, or place them after a trailing `--`. %s"
|
|
positionalConsumers.[0]
|
|
x
|
|
)
|
|
|> errors.Add
|
|
else
|
|
()
|
|
|
|
if errors.Count = 0 then
|
|
Ok (
|
|
{
|
|
A = arg0
|
|
},
|
|
Seq.tryExactlyOne positionalConsumers
|
|
)
|
|
else
|
|
errors |> Seq.toList |> Error
|
|
else
|
|
("Multiple parsers consumed positional args; this is an error in the application, not an error by the user: "
|
|
+ String.concat ", " positionalConsumers)
|
|
|> List.singleton
|
|
|> Error
|
|
|
|
static member _Empty () : PassThru_InProgress =
|
|
{
|
|
A = ParentRecordChildPos_InProgress._Empty ()
|
|
}
|
|
|
|
/// Passes the key-value pair to any child records, returning Error if no key was matched.
|
|
/// If the key is an arg which can have arity 1, but throws when consuming that arg, we return Error(<the message>).
|
|
/// This can nevertheless be a successful parse, e.g. when the key may have arity 0.
|
|
member this.ProcessKeyValueRecord_
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
let errors : ResizeArray<string> = ResizeArray ()
|
|
|
|
match this.A.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error e -> Error None
|
|
|
|
member this.ProcessKeyValue
|
|
(argNum_ : int)
|
|
(errors_ : ResizeArray<string>)
|
|
(key : string)
|
|
(value : string)
|
|
: Result<unit, string option>
|
|
=
|
|
match this.ProcessKeyValueRecord_ argNum_ errors_ key value with
|
|
| Ok () -> Ok ()
|
|
| Error errorFromRecord -> Error errorFromRecord
|
|
|
|
/// Returns false if we didn't set a value.
|
|
member this.SetFlagValue_ (errors_ : ResizeArray<string>) (key : string) : bool = false
|
|
/// Compute help text for this parser, optionally noting the given prefix on each argument and indenting each line by this many spaces.
|
|
static member HelpText_ (prefix : string option) (indent : int) : string = failwith "TODO"
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type BasicNoPositionals
|
|
[<RequireQualifiedAccess ; CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
|
|
module BasicNoPositionals =
|
|
type internal ParseState_BasicNoPositionals =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
let parse' (getEnvironmentVariable : string -> string) (args : string list) : BasicNoPositionals =
|
|
let inProgress =
|
|
ArgParseHelpers_ConsumePlugin.BasicNoPositionals_InProgress._Empty ()
|
|
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_BasicNoPositionals) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_BasicNoPositionals.AwaitingKey -> ()
|
|
| ParseState_BasicNoPositionals.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest -> positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_BasicNoPositionals.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_BasicNoPositionals.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_BasicNoPositionals.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_BasicNoPositionals.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_BasicNoPositionals.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_BasicNoPositionals.AwaitingKey args
|
|
| ParseState_BasicNoPositionals.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_BasicNoPositionals.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_BasicNoPositionals.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_BasicNoPositionals.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_BasicNoPositionals.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
let parse (args : string list) : BasicNoPositionals =
|
|
parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type Basic
|
|
[<RequireQualifiedAccess ; CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
|
|
module Basic =
|
|
type internal ParseState_Basic =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
let parse' (getEnvironmentVariable : string -> string) (args : string list) : Basic =
|
|
let inProgress = ArgParseHelpers_ConsumePlugin.Basic_InProgress._Empty ()
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_Basic) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_Basic.AwaitingKey -> ()
|
|
| ParseState_Basic.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest -> positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_Basic.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_Basic.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_Basic.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_Basic.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_Basic.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_Basic.AwaitingKey args
|
|
| ParseState_Basic.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_Basic.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_Basic.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_Basic.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_Basic.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
let parse (args : string list) : Basic =
|
|
parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type BasicWithIntPositionals
|
|
[<RequireQualifiedAccess ; CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
|
|
module BasicWithIntPositionals =
|
|
type internal ParseState_BasicWithIntPositionals =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
let parse' (getEnvironmentVariable : string -> string) (args : string list) : BasicWithIntPositionals =
|
|
let inProgress =
|
|
ArgParseHelpers_ConsumePlugin.BasicWithIntPositionals_InProgress._Empty ()
|
|
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_BasicWithIntPositionals) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_BasicWithIntPositionals.AwaitingKey -> ()
|
|
| ParseState_BasicWithIntPositionals.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest -> positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_BasicWithIntPositionals.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_BasicWithIntPositionals.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_BasicWithIntPositionals.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_BasicWithIntPositionals.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_BasicWithIntPositionals.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_BasicWithIntPositionals.AwaitingKey args
|
|
| ParseState_BasicWithIntPositionals.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_BasicWithIntPositionals.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_BasicWithIntPositionals.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_BasicWithIntPositionals.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_BasicWithIntPositionals.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
let parse (args : string list) : BasicWithIntPositionals =
|
|
parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type LoadsOfTypes
|
|
[<RequireQualifiedAccess ; CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
|
|
module LoadsOfTypes =
|
|
type internal ParseState_LoadsOfTypes =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
let parse' (getEnvironmentVariable : string -> string) (args : string list) : LoadsOfTypes =
|
|
let inProgress = ArgParseHelpers_ConsumePlugin.LoadsOfTypes_InProgress._Empty ()
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_LoadsOfTypes) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_LoadsOfTypes.AwaitingKey -> ()
|
|
| ParseState_LoadsOfTypes.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest -> positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_LoadsOfTypes.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_LoadsOfTypes.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_LoadsOfTypes.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_LoadsOfTypes.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_LoadsOfTypes.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_LoadsOfTypes.AwaitingKey args
|
|
| ParseState_LoadsOfTypes.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_LoadsOfTypes.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_LoadsOfTypes.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_LoadsOfTypes.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_LoadsOfTypes.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
let parse (args : string list) : LoadsOfTypes =
|
|
parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type LoadsOfTypesNoPositionals
|
|
[<RequireQualifiedAccess ; CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
|
|
module LoadsOfTypesNoPositionals =
|
|
type internal ParseState_LoadsOfTypesNoPositionals =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
let parse' (getEnvironmentVariable : string -> string) (args : string list) : LoadsOfTypesNoPositionals =
|
|
let inProgress =
|
|
ArgParseHelpers_ConsumePlugin.LoadsOfTypesNoPositionals_InProgress._Empty ()
|
|
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_LoadsOfTypesNoPositionals) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_LoadsOfTypesNoPositionals.AwaitingKey -> ()
|
|
| ParseState_LoadsOfTypesNoPositionals.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest -> positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_LoadsOfTypesNoPositionals.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_LoadsOfTypesNoPositionals.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_LoadsOfTypesNoPositionals.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_LoadsOfTypesNoPositionals.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_LoadsOfTypesNoPositionals.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_LoadsOfTypesNoPositionals.AwaitingKey args
|
|
| ParseState_LoadsOfTypesNoPositionals.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_LoadsOfTypesNoPositionals.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_LoadsOfTypesNoPositionals.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_LoadsOfTypesNoPositionals.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_LoadsOfTypesNoPositionals.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
let parse (args : string list) : LoadsOfTypesNoPositionals =
|
|
parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type DatesAndTimes
|
|
[<AutoOpen>]
|
|
module DatesAndTimesArgParse =
|
|
type internal ParseState_DatesAndTimes =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type DatesAndTimes with
|
|
|
|
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : DatesAndTimes =
|
|
let inProgress = ArgParseHelpers_ConsumePlugin.DatesAndTimes_InProgress._Empty ()
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_DatesAndTimes) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_DatesAndTimes.AwaitingKey -> ()
|
|
| ParseState_DatesAndTimes.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_DatesAndTimes.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_DatesAndTimes.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_DatesAndTimes.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_DatesAndTimes.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_DatesAndTimes.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_DatesAndTimes.AwaitingKey args
|
|
| ParseState_DatesAndTimes.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_DatesAndTimes.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_DatesAndTimes.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_DatesAndTimes.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_DatesAndTimes.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : DatesAndTimes =
|
|
DatesAndTimes.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type ParentRecord
|
|
[<AutoOpen>]
|
|
module ParentRecordArgParse =
|
|
type internal ParseState_ParentRecord =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type ParentRecord with
|
|
|
|
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ParentRecord =
|
|
let inProgress = ArgParseHelpers_ConsumePlugin.ParentRecord_InProgress._Empty ()
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_ParentRecord) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_ParentRecord.AwaitingKey -> ()
|
|
| ParseState_ParentRecord.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_ParentRecord.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_ParentRecord.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_ParentRecord.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_ParentRecord.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_ParentRecord.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ParentRecord.AwaitingKey args
|
|
| ParseState_ParentRecord.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_ParentRecord.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_ParentRecord.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ParentRecord.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_ParentRecord.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : ParentRecord =
|
|
ParentRecord.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type ParentRecordChildPos
|
|
[<AutoOpen>]
|
|
module ParentRecordChildPosArgParse =
|
|
type internal ParseState_ParentRecordChildPos =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type ParentRecordChildPos with
|
|
|
|
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ParentRecordChildPos =
|
|
let inProgress =
|
|
ArgParseHelpers_ConsumePlugin.ParentRecordChildPos_InProgress._Empty ()
|
|
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_ParentRecordChildPos) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_ParentRecordChildPos.AwaitingKey -> ()
|
|
| ParseState_ParentRecordChildPos.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_ParentRecordChildPos.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_ParentRecordChildPos.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_ParentRecordChildPos.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_ParentRecordChildPos.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_ParentRecordChildPos.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ParentRecordChildPos.AwaitingKey args
|
|
| ParseState_ParentRecordChildPos.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_ParentRecordChildPos.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_ParentRecordChildPos.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ParentRecordChildPos.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_ParentRecordChildPos.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : ParentRecordChildPos =
|
|
ParentRecordChildPos.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type ParentRecordSelfPos
|
|
[<AutoOpen>]
|
|
module ParentRecordSelfPosArgParse =
|
|
type internal ParseState_ParentRecordSelfPos =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type ParentRecordSelfPos with
|
|
|
|
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ParentRecordSelfPos =
|
|
let inProgress =
|
|
ArgParseHelpers_ConsumePlugin.ParentRecordSelfPos_InProgress._Empty ()
|
|
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_ParentRecordSelfPos) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_ParentRecordSelfPos.AwaitingKey -> ()
|
|
| ParseState_ParentRecordSelfPos.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_ParentRecordSelfPos.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_ParentRecordSelfPos.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_ParentRecordSelfPos.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_ParentRecordSelfPos.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_ParentRecordSelfPos.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ParentRecordSelfPos.AwaitingKey args
|
|
| ParseState_ParentRecordSelfPos.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_ParentRecordSelfPos.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_ParentRecordSelfPos.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ParentRecordSelfPos.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_ParentRecordSelfPos.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : ParentRecordSelfPos =
|
|
ParentRecordSelfPos.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type ChoicePositionals
|
|
[<AutoOpen>]
|
|
module ChoicePositionalsArgParse =
|
|
type internal ParseState_ChoicePositionals =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type ChoicePositionals with
|
|
|
|
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ChoicePositionals =
|
|
let inProgress =
|
|
ArgParseHelpers_ConsumePlugin.ChoicePositionals_InProgress._Empty ()
|
|
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_ChoicePositionals) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_ChoicePositionals.AwaitingKey -> ()
|
|
| ParseState_ChoicePositionals.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_ChoicePositionals.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_ChoicePositionals.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_ChoicePositionals.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_ChoicePositionals.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_ChoicePositionals.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ChoicePositionals.AwaitingKey args
|
|
| ParseState_ChoicePositionals.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_ChoicePositionals.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_ChoicePositionals.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ChoicePositionals.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_ChoicePositionals.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : ChoicePositionals =
|
|
ChoicePositionals.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type ContainsBoolEnvVar
|
|
[<AutoOpen>]
|
|
module ContainsBoolEnvVarArgParse =
|
|
type internal ParseState_ContainsBoolEnvVar =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type ContainsBoolEnvVar with
|
|
|
|
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ContainsBoolEnvVar =
|
|
let inProgress =
|
|
ArgParseHelpers_ConsumePlugin.ContainsBoolEnvVar_InProgress._Empty ()
|
|
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_ContainsBoolEnvVar) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_ContainsBoolEnvVar.AwaitingKey -> ()
|
|
| ParseState_ContainsBoolEnvVar.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_ContainsBoolEnvVar.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_ContainsBoolEnvVar.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_ContainsBoolEnvVar.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_ContainsBoolEnvVar.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_ContainsBoolEnvVar.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ContainsBoolEnvVar.AwaitingKey args
|
|
| ParseState_ContainsBoolEnvVar.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_ContainsBoolEnvVar.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_ContainsBoolEnvVar.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ContainsBoolEnvVar.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_ContainsBoolEnvVar.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : ContainsBoolEnvVar =
|
|
ContainsBoolEnvVar.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type WithFlagDu
|
|
[<AutoOpen>]
|
|
module WithFlagDuArgParse =
|
|
type internal ParseState_WithFlagDu =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type WithFlagDu with
|
|
|
|
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : WithFlagDu =
|
|
let inProgress = ArgParseHelpers_ConsumePlugin.WithFlagDu_InProgress._Empty ()
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_WithFlagDu) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_WithFlagDu.AwaitingKey -> ()
|
|
| ParseState_WithFlagDu.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_WithFlagDu.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_WithFlagDu.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_WithFlagDu.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_WithFlagDu.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_WithFlagDu.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_WithFlagDu.AwaitingKey args
|
|
| ParseState_WithFlagDu.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_WithFlagDu.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_WithFlagDu.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_WithFlagDu.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_WithFlagDu.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : WithFlagDu =
|
|
WithFlagDu.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type ContainsFlagEnvVar
|
|
[<AutoOpen>]
|
|
module ContainsFlagEnvVarArgParse =
|
|
type internal ParseState_ContainsFlagEnvVar =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type ContainsFlagEnvVar with
|
|
|
|
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ContainsFlagEnvVar =
|
|
let inProgress =
|
|
ArgParseHelpers_ConsumePlugin.ContainsFlagEnvVar_InProgress._Empty ()
|
|
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_ContainsFlagEnvVar) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_ContainsFlagEnvVar.AwaitingKey -> ()
|
|
| ParseState_ContainsFlagEnvVar.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_ContainsFlagEnvVar.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_ContainsFlagEnvVar.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_ContainsFlagEnvVar.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_ContainsFlagEnvVar.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_ContainsFlagEnvVar.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ContainsFlagEnvVar.AwaitingKey args
|
|
| ParseState_ContainsFlagEnvVar.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_ContainsFlagEnvVar.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_ContainsFlagEnvVar.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ContainsFlagEnvVar.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_ContainsFlagEnvVar.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : ContainsFlagEnvVar =
|
|
ContainsFlagEnvVar.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type ContainsFlagDefaultValue
|
|
[<AutoOpen>]
|
|
module ContainsFlagDefaultValueArgParse =
|
|
type internal ParseState_ContainsFlagDefaultValue =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type ContainsFlagDefaultValue with
|
|
|
|
static member parse'
|
|
(getEnvironmentVariable : string -> string)
|
|
(args : string list)
|
|
: ContainsFlagDefaultValue
|
|
=
|
|
let inProgress =
|
|
ArgParseHelpers_ConsumePlugin.ContainsFlagDefaultValue_InProgress._Empty ()
|
|
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_ContainsFlagDefaultValue) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_ContainsFlagDefaultValue.AwaitingKey -> ()
|
|
| ParseState_ContainsFlagDefaultValue.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_ContainsFlagDefaultValue.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_ContainsFlagDefaultValue.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_ContainsFlagDefaultValue.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_ContainsFlagDefaultValue.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_ContainsFlagDefaultValue.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ContainsFlagDefaultValue.AwaitingKey args
|
|
| ParseState_ContainsFlagDefaultValue.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_ContainsFlagDefaultValue.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_ContainsFlagDefaultValue.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ContainsFlagDefaultValue.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_ContainsFlagDefaultValue.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : ContainsFlagDefaultValue =
|
|
ContainsFlagDefaultValue.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type ManyLongForms
|
|
[<AutoOpen>]
|
|
module ManyLongFormsArgParse =
|
|
type internal ParseState_ManyLongForms =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type ManyLongForms with
|
|
|
|
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : ManyLongForms =
|
|
let inProgress = ArgParseHelpers_ConsumePlugin.ManyLongForms_InProgress._Empty ()
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_ManyLongForms) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_ManyLongForms.AwaitingKey -> ()
|
|
| ParseState_ManyLongForms.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_ManyLongForms.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_ManyLongForms.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_ManyLongForms.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_ManyLongForms.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_ManyLongForms.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ManyLongForms.AwaitingKey args
|
|
| ParseState_ManyLongForms.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_ManyLongForms.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_ManyLongForms.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_ManyLongForms.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_ManyLongForms.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : ManyLongForms =
|
|
ManyLongForms.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type FlagsIntoPositionalArgs
|
|
[<AutoOpen>]
|
|
module FlagsIntoPositionalArgsArgParse =
|
|
type internal ParseState_FlagsIntoPositionalArgs =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type FlagsIntoPositionalArgs with
|
|
|
|
static member parse'
|
|
(getEnvironmentVariable : string -> string)
|
|
(args : string list)
|
|
: FlagsIntoPositionalArgs
|
|
=
|
|
let inProgress =
|
|
ArgParseHelpers_ConsumePlugin.FlagsIntoPositionalArgs_InProgress._Empty ()
|
|
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_FlagsIntoPositionalArgs) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_FlagsIntoPositionalArgs.AwaitingKey -> ()
|
|
| ParseState_FlagsIntoPositionalArgs.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_FlagsIntoPositionalArgs.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_FlagsIntoPositionalArgs.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_FlagsIntoPositionalArgs.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgs.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgs.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgs.AwaitingKey args
|
|
| ParseState_FlagsIntoPositionalArgs.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_FlagsIntoPositionalArgs.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_FlagsIntoPositionalArgs.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgs.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_FlagsIntoPositionalArgs.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : FlagsIntoPositionalArgs =
|
|
FlagsIntoPositionalArgs.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type FlagsIntoPositionalArgsChoice
|
|
[<AutoOpen>]
|
|
module FlagsIntoPositionalArgsChoiceArgParse =
|
|
type internal ParseState_FlagsIntoPositionalArgsChoice =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type FlagsIntoPositionalArgsChoice with
|
|
|
|
static member parse'
|
|
(getEnvironmentVariable : string -> string)
|
|
(args : string list)
|
|
: FlagsIntoPositionalArgsChoice
|
|
=
|
|
let inProgress =
|
|
ArgParseHelpers_ConsumePlugin.FlagsIntoPositionalArgsChoice_InProgress._Empty ()
|
|
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_FlagsIntoPositionalArgsChoice) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_FlagsIntoPositionalArgsChoice.AwaitingKey -> ()
|
|
| ParseState_FlagsIntoPositionalArgsChoice.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_FlagsIntoPositionalArgsChoice.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_FlagsIntoPositionalArgsChoice.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () ->
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgsChoice.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgsChoice.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgsChoice.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgsChoice.AwaitingKey args
|
|
| ParseState_FlagsIntoPositionalArgsChoice.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_FlagsIntoPositionalArgsChoice.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_FlagsIntoPositionalArgsChoice.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgsChoice.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_FlagsIntoPositionalArgsChoice.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : FlagsIntoPositionalArgsChoice =
|
|
FlagsIntoPositionalArgsChoice.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type FlagsIntoPositionalArgsInt
|
|
[<AutoOpen>]
|
|
module FlagsIntoPositionalArgsIntArgParse =
|
|
type internal ParseState_FlagsIntoPositionalArgsInt =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type FlagsIntoPositionalArgsInt with
|
|
|
|
static member parse'
|
|
(getEnvironmentVariable : string -> string)
|
|
(args : string list)
|
|
: FlagsIntoPositionalArgsInt
|
|
=
|
|
let inProgress =
|
|
ArgParseHelpers_ConsumePlugin.FlagsIntoPositionalArgsInt_InProgress._Empty ()
|
|
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_FlagsIntoPositionalArgsInt) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_FlagsIntoPositionalArgsInt.AwaitingKey -> ()
|
|
| ParseState_FlagsIntoPositionalArgsInt.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_FlagsIntoPositionalArgsInt.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_FlagsIntoPositionalArgsInt.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_FlagsIntoPositionalArgsInt.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgsInt.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgsInt.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgsInt.AwaitingKey args
|
|
| ParseState_FlagsIntoPositionalArgsInt.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_FlagsIntoPositionalArgsInt.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_FlagsIntoPositionalArgsInt.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgsInt.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_FlagsIntoPositionalArgsInt.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : FlagsIntoPositionalArgsInt =
|
|
FlagsIntoPositionalArgsInt.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type FlagsIntoPositionalArgsIntChoice
|
|
[<AutoOpen>]
|
|
module FlagsIntoPositionalArgsIntChoiceArgParse =
|
|
type internal ParseState_FlagsIntoPositionalArgsIntChoice =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type FlagsIntoPositionalArgsIntChoice with
|
|
|
|
static member parse'
|
|
(getEnvironmentVariable : string -> string)
|
|
(args : string list)
|
|
: FlagsIntoPositionalArgsIntChoice
|
|
=
|
|
let inProgress =
|
|
ArgParseHelpers_ConsumePlugin.FlagsIntoPositionalArgsIntChoice_InProgress._Empty ()
|
|
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_FlagsIntoPositionalArgsIntChoice) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_FlagsIntoPositionalArgsIntChoice.AwaitingKey -> ()
|
|
| ParseState_FlagsIntoPositionalArgsIntChoice.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_FlagsIntoPositionalArgsIntChoice.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go
|
|
(argNum_ + 1)
|
|
(ParseState_FlagsIntoPositionalArgsIntChoice.AwaitingValue arg)
|
|
args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () ->
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgsIntChoice.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
|
|
go
|
|
(argNum_ + 1)
|
|
ParseState_FlagsIntoPositionalArgsIntChoice.AwaitingKey
|
|
args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
|
|
go
|
|
(argNum_ + 1)
|
|
ParseState_FlagsIntoPositionalArgsIntChoice.AwaitingKey
|
|
args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgsIntChoice.AwaitingKey args
|
|
| ParseState_FlagsIntoPositionalArgsIntChoice.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_FlagsIntoPositionalArgsIntChoice.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_FlagsIntoPositionalArgsIntChoice.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgsIntChoice.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_FlagsIntoPositionalArgsIntChoice.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : FlagsIntoPositionalArgsIntChoice =
|
|
FlagsIntoPositionalArgsIntChoice.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type FlagsIntoPositionalArgs'
|
|
[<AutoOpen>]
|
|
module FlagsIntoPositionalArgs'ArgParse =
|
|
type internal ParseState_FlagsIntoPositionalArgs' =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type FlagsIntoPositionalArgs' with
|
|
|
|
static member parse'
|
|
(getEnvironmentVariable : string -> string)
|
|
(args : string list)
|
|
: FlagsIntoPositionalArgs'
|
|
=
|
|
let inProgress =
|
|
ArgParseHelpers_ConsumePlugin.FlagsIntoPositionalArgs'_InProgress._Empty ()
|
|
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_FlagsIntoPositionalArgs') (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_FlagsIntoPositionalArgs'.AwaitingKey -> ()
|
|
| ParseState_FlagsIntoPositionalArgs'.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_FlagsIntoPositionalArgs'.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_FlagsIntoPositionalArgs'.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_FlagsIntoPositionalArgs'.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgs'.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgs'.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgs'.AwaitingKey args
|
|
| ParseState_FlagsIntoPositionalArgs'.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_FlagsIntoPositionalArgs'.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_FlagsIntoPositionalArgs'.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_FlagsIntoPositionalArgs'.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_FlagsIntoPositionalArgs'.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : FlagsIntoPositionalArgs' =
|
|
FlagsIntoPositionalArgs'.parse' System.Environment.GetEnvironmentVariable args
|
|
namespace ConsumePlugin
|
|
|
|
open ArgParserHelpers
|
|
open System
|
|
open System.IO
|
|
open WoofWare.Myriad.Plugins
|
|
|
|
/// Methods to parse arguments for the type PassThru
|
|
[<AutoOpen>]
|
|
module PassThruArgParse =
|
|
type internal ParseState_PassThru =
|
|
/// Ready to consume a key or positional arg
|
|
| AwaitingKey
|
|
/// Waiting to receive a value for the key we've already consumed
|
|
| AwaitingValue of key : string
|
|
|
|
/// Extension methods for argument parsing
|
|
type PassThru with
|
|
|
|
static member parse' (getEnvironmentVariable : string -> string) (args : string list) : PassThru =
|
|
let inProgress = ArgParseHelpers_ConsumePlugin.PassThru_InProgress._Empty ()
|
|
let positionals : ResizeArray<Choice<string * int, string * int>> = ResizeArray ()
|
|
let errors_ = ResizeArray ()
|
|
|
|
let rec go (argNum_ : int) (state : ParseState_PassThru) (args : string list) =
|
|
match args with
|
|
| [] ->
|
|
match state with
|
|
| ParseState_PassThru.AwaitingKey -> ()
|
|
| ParseState_PassThru.AwaitingValue key ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
()
|
|
else
|
|
sprintf
|
|
"Trailing argument %s had no value. Use a double-dash to separate positional args from key-value args."
|
|
key
|
|
|> errors_.Add
|
|
| "--" :: rest ->
|
|
positionals.AddRange (rest |> Seq.map (fun x -> (x, argNum_ + 1)) |> Seq.map Choice2Of2)
|
|
| arg :: args ->
|
|
match state with
|
|
| ParseState_PassThru.AwaitingKey ->
|
|
if arg.StartsWith ("--", System.StringComparison.Ordinal) then
|
|
if arg = "--help" then
|
|
"TODO" |> failwithf "Help text requested.\n%s"
|
|
else
|
|
let equals = arg.IndexOf (char 61)
|
|
|
|
if equals < 0 then
|
|
go (argNum_ + 1) (ParseState_PassThru.AwaitingValue arg) args
|
|
else
|
|
let key = arg.[0 .. equals - 1]
|
|
let value = arg.[equals + 1 ..]
|
|
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key value with
|
|
| Ok () -> go (argNum_ + 1) ParseState_PassThru.AwaitingKey args
|
|
| Error x ->
|
|
match x with
|
|
| None ->
|
|
positionals.Add (Choice1Of2 (arg, argNum_))
|
|
go (argNum_ + 1) ParseState_PassThru.AwaitingKey args
|
|
| Some msg ->
|
|
sprintf "%s (at arg %s)" msg arg |> errors_.Add
|
|
go (argNum_ + 1) ParseState_PassThru.AwaitingKey args
|
|
else
|
|
(arg, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_PassThru.AwaitingKey args
|
|
| ParseState_PassThru.AwaitingValue key ->
|
|
match inProgress.ProcessKeyValue argNum_ errors_ key arg with
|
|
| Ok () -> go argNum_ ParseState_PassThru.AwaitingKey args
|
|
| Error exc ->
|
|
if inProgress.SetFlagValue_ errors_ key then
|
|
go argNum_ ParseState_PassThru.AwaitingKey (arg :: args)
|
|
else
|
|
(key, argNum_) |> Choice1Of2 |> positionals.Add
|
|
go (argNum_ + 1) ParseState_PassThru.AwaitingKey (arg :: args)
|
|
|
|
go 0 ParseState_PassThru.AwaitingKey args
|
|
|
|
if 0 = errors_.Count then
|
|
()
|
|
else
|
|
errors_
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
match inProgress.Assemble_ getEnvironmentVariable (positionals |> Seq.toList) with
|
|
| Ok (result, posConsumer) ->
|
|
if positionals.Count > 0 && posConsumer.IsNone then
|
|
positionals
|
|
|> Seq.map (fun choiceValue ->
|
|
match choiceValue with
|
|
| Choice1Of2 (arg, _) -> arg
|
|
| Choice2Of2 (arg, _) -> arg
|
|
)
|
|
|> String.concat " "
|
|
|> sprintf "Parse error: The following arguments were not consumed: %s"
|
|
|> failwith
|
|
else
|
|
result
|
|
| Error e ->
|
|
e
|
|
|> String.concat System.Environment.NewLine
|
|
|> (fun x -> "Errors during parse!\n" + x)
|
|
|> failwith
|
|
|
|
static member parse (args : string list) : PassThru =
|
|
PassThru.parse' System.Environment.GetEnvironmentVariable args
|