WoofWare.Myriad.Plugins
1.0.6
See the version list below for details.
dotnet add package WoofWare.Myriad.Plugins --version 1.0.6
NuGet\Install-Package WoofWare.Myriad.Plugins -Version 1.0.6
<PackageReference Include="WoofWare.Myriad.Plugins" Version="1.0.6" />
<PackageVersion Include="WoofWare.Myriad.Plugins" Version="1.0.6" />
<PackageReference Include="WoofWare.Myriad.Plugins" />
paket add WoofWare.Myriad.Plugins --version 1.0.6
#r "nuget: WoofWare.Myriad.Plugins, 1.0.6"
#:package WoofWare.Myriad.Plugins@1.0.6
#addin nuget:?package=WoofWare.Myriad.Plugins&version=1.0.6
#tool nuget:?package=WoofWare.Myriad.Plugins&version=1.0.6
WoofWare.Myriad.Plugins
Some helpers in 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 outjsonParse : JsonNode -> 'Tmethods);RemoveOptions(to stripoptionmodifiers from a type).
JsonParse
Takes records like this:
[<MyriadPlugin.JsonParse>]
type InnerType =
{
[<JsonPropertyName "something">]
Thing : string
}
/// My whatnot
[<MyriadPlugin.JsonParse>]
type JsonRecordType =
{
/// A thing!
A : int
/// Another thing!
B : string
[<System.Text.Json.Serialization.JsonPropertyName "hi">]
C : int list
D : InnerType
}
and stamps out parsing methods like this:
/// Module containing JSON parsing methods for the InnerType type
[<RequireQualifiedAccess>]
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module InnerType =
/// Parse from a JSON node.
let jsonParse (node: System.Text.Json.Nodes.JsonNode) : InnerType =
let Thing = node.["something"].AsValue().GetValue<string>()
{ Thing = Thing }
namespace UsePlugin
/// Module containing JSON parsing methods for the JsonRecordType type
[<RequireQualifiedAccess>]
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
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<int>()) |> List.ofSeq
let B = node.["b"].AsValue().GetValue<string>()
let A = node.["a"].AsValue().GetValue<int>()
{ 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#.
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.Jsonattributes.
RemoveOptions
Takes a record like this:
type Foo =
{
A : int option
B : string
C : float list
}
and stamps out a record like this:
[<RequireQualifiedAccess>]
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 is a real-world set of DTOs.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net6.0
- FSharp.Core (>= 6.0.1)
- Myriad.Core (>= 0.8.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 11.0.5 | 40 | 8/25/2026 |
| 11.0.4 | 43 | 8/25/2026 |
| 11.0.3 | 106 | 7/31/2026 |
| 11.0.2 | 98 | 7/31/2026 |
| 11.0.1 | 99 | 7/30/2026 |
| 10.7.3 | 95 | 7/30/2026 |
| 10.7.2 | 99 | 7/30/2026 |
| 10.7.1 | 103 | 7/30/2026 |
| 10.6.2 | 107 | 7/29/2026 |
| 10.6.1 | 92 | 7/29/2026 |
| 10.5.2 | 98 | 7/29/2026 |
| 10.5.1 | 99 | 7/29/2026 |
| 10.4.1 | 100 | 7/29/2026 |
| 10.3.2 | 100 | 7/28/2026 |
| 10.3.1 | 131 | 7/25/2026 |
| 10.2.10 | 99 | 7/25/2026 |
| 10.2.9 | 103 | 7/25/2026 |
| 10.2.8 | 105 | 7/25/2026 |
| 10.2.7 | 99 | 7/25/2026 |
| 1.0.6 | 249 | 12/28/2023 |