# WoofWare.Myriad.Plugins Some helpers in [Myriad](https://github.com/MoiraeSoftware/myriad/) which might be useful. These are currently somewhat experimental, and I personally am their primary customer. The `RemoveOptions` generator in particular is extremely half-baked. Currently implemented: * `JsonParse` (to stamp out `jsonParse : JsonNode -> 'T` methods); * `RemoveOptions` (to strip `option` modifiers from a type). ## `JsonParse` Takes records like this: ```fsharp [] type InnerType = { [] Thing : string } /// My whatnot [] type JsonRecordType = { /// A thing! A : int /// Another thing! B : string [] C : int list D : InnerType } ``` and stamps out parsing methods like this: ```fsharp /// Module containing JSON parsing methods for the InnerType type [] [] module InnerType = /// Parse from a JSON node. let jsonParse (node: System.Text.Json.Nodes.JsonNode) : InnerType = let Thing = node.["something"].AsValue().GetValue() { Thing = Thing } namespace UsePlugin /// Module containing JSON parsing methods for the JsonRecordType type [] [] module JsonRecordType = /// Parse from a JSON node. let jsonParse (node: System.Text.Json.Nodes.JsonNode) : JsonRecordType = let D = InnerType.jsonParse node.["d"] let C = node.["hi"].AsArray() |> Seq.map (fun elt -> elt.GetValue()) |> List.ofSeq let B = node.["b"].AsValue().GetValue() let A = node.["a"].AsValue().GetValue() { A = A; B = B; C = C; D = D } ``` ### What's the point? `System.Text.Json`, in a `PublishAot` context, relies on C# source generators. The default reflection-heavy implementations have the necessary code trimmed away, and result in a runtime exception. But C# source generators [are entirely unsupported in F#](https://github.com/dotnet/fsharp/issues/14300). This Myriad generator expects you to use `System.Text.Json` to construct a `JsonNode`, and then the generator takes over to construct a strongly-typed object. ### Limitations This source generator is enough for what I first wanted to use it for. However, there is *far* more that could be done. * Make it possible to give an exact format and cultural info in date and time parsing. * Make it possible to reject parsing if extra fields are present. * Rather than just throwing `NullReferenceException`, print out the field name that failed. * Generally support all the `System.Text.Json` attributes. ## `RemoveOptions` Takes a record like this: ```fsharp type Foo = { A : int option B : string C : float list } ``` and stamps out a record like this: ```fsharp [] module Foo = type Short = { A : int B : string C : float list } ``` ### What's the point? The motivating example is argument parsing. An argument parser naturally wants to express "the user did not supply this, so I will provide a default". But it's not a very ergonomic experience for the programmer to deal with all these options, so this Myriad generator stamps out a type *without* any options, and also stamps out an appropriate constructor function. ### Limitations This generator is *far* from where I want it, because I haven't really spent any time on it. * It really wants to be able to recurse into the types within the record, to strip options from them. * It needs some sort of attribute to mark a field as *not* receiving this treatment. * What do we do about discriminated unions? # Detailed examples See the tests. For example, [PureGymDto.fs](./ConsumePlugin/PureGymDto.fs) is a real-world set of DTOs.