--- lastmod: "2024-08-26T12:26:00.0000000+01:00" author: patrick categories: - uncategorized date: "2024-08-26T12:26:00.0000000+01:00" title: WoofWare.Myriad.Plugins learns to parse args summary: "My F# source generators have some new features, including an argument parser." --- This post is about [WoofWare.Myriad.Plugins](https://github.com/Smaug123/WoofWare.Myriad), a set of [F#](https://en.wikipedia.org/wiki/F_Sharp_(programming_language)) source generators ([see it on NuGet](https://www.nuget.org/packages/WoofWare.Myriad.Plugins)). Go and read [the README on GitHub](https://github.com/Smaug123/WoofWare.Myriad/blob/main/README.md) if you're interested. They are particularly intended for `PublishAot` [ahead-of-time compilation](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/) contexts, in which reflection is heavily restricted, but also for anyone who doesn't want reflection for whatever reason (e.g. "to obtain the ability to step through code in a debugger", or "for more predictable speed"). Since [my last post], I've implemented the following: * `[]` (to stamp out `toJsonNode : 'T -> JsonNode` methods) * `[]` (to build a non-stack-overflowing [catamorphism](https://fsharpforfunandprofit.com/posts/recursive-types-and-folds/) for an algebraic data type) * `[]` (to stamp out an argument parser). ## `ArgParser` Example: ```fsharp [] type Foo = { [] SomeFlag : bool A : int option [] B : Choice [] BWithEnv : Choice C : float list // optionally: [] Rest : string list // or e.g. `int list` if you want them parsed into a type too } static member DefaultB () = 4 ``` Features: * Optional arguments of type `'a option`. * `[]` and `[]` to auto-populate default arguments which are not supplied. Default values are modelled as `Choice<'a, 'a>`, with `Choice1Of2` meaning "the user gave me this", and `Choice2Of2` meaning "this was populated from a default source". * Help text with `[]`, summoned with `--help` in any position where the parser is expecting an argument, and also summoned during certain failures to parse. * Detailed control over `TimeSpan` parsing with `[]` (and `[]` if desired). * Accumulation of arguments supplied repeatedly: for example, `Path : FileInfo list` is populated with `--path /foo/bar --path /baz/quux`. * Handling of `--foo=bar` and `--foo bar` equivalently. * Booleans have arity 1 or 0, whichever leads to a successful parse: `--flag` and `--flag=true` and `--flag true` are equivalent. * Positional arguments can appear anywhere, although if they start with a `--` then it is best to put them after a trailing `--` separator: `--named-arg=blah -- --pos-arg1 pos-arg2 --pos-arg3`. [my last post]: {{< ref "2023-12-31-woofware-myriad-plugins" >}}