WoofWare.Whippet.Plugin.Json
0.1.6
dotnet add package WoofWare.Whippet.Plugin.Json --version 0.1.6
NuGet\Install-Package WoofWare.Whippet.Plugin.Json -Version 0.1.6
<PackageReference Include="WoofWare.Whippet.Plugin.Json" Version="0.1.6"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add WoofWare.Whippet.Plugin.Json --version 0.1.6
#r "nuget: WoofWare.Whippet.Plugin.Json, 0.1.6"
// Install WoofWare.Whippet.Plugin.Json as a Cake Addin #addin nuget:?package=WoofWare.Whippet.Plugin.Json&version=0.1.6 // Install WoofWare.Whippet.Plugin.Json as a Cake Tool #tool nuget:?package=WoofWare.Whippet.Plugin.Json&version=0.1.6
WoofWare.Whippet.Plugin.Json
This is a Whippet plugin defining JSON parse and serialise methods.
It is a copy of the corresponding Myriad JSON plugin in WoofWare.Myriad, taken from commit d59ebdfccb87a06579fb99008a15f58ea8be394e.
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#.
These generators handle going from your strongly-typed domain objects to System.Text.Json.Nodes.JsonNode
, and back.
Usage: JsonParse
Define a Dto.fs
file like the following:
namespace MyNamespace
open WoofWare.Whippet.Plugin.Json
[<JsonParse>]
type InnerType =
{
[<JsonPropertyName "something">]
Thing : string
}
/// My whatnot
[<JsonParse (* isExtensionMethod = *) false>]
type JsonRecordType =
{
/// A thing!
A : int
/// Another thing!
B : string
[<System.Text.Json.Serialization.JsonPropertyName "hi">]
C : int list
D : InnerType
}
In your fsproj:
<Project>
<ItemGroup>
<Compile Include="Dto.fs" />
<Compile Include="GeneratedDto.fs">
<WhippetFile>Dto.fs</WhippetFile>
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="WoofWare.Whippet.Plugin.Json.Attributes" Version="" />
<PackageReference Include="WoofWare.Whippet.Plugin.Json" WhippetPlugin="true" Version="" />
<PackageReference Include="WoofWare.Whippet" Version="" PrivateAssets="all" />
</ItemGroup>
</Project>
The generator will produce a file somewhat like the following:
/// 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
[<AutoOpen>]
module JsonRecordTypeExtension =
type JsonRecordType with
/// 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 }
You may instead choose to define attributes with the correct name yourself (if you don't want to take a dependency on the WoofWare.Whippet.Plugin.Json.Attributes
package).
Alternatively, you may omit the attributes and the runtime dependency, and control the generator entirely through the fsproj file:
<Project>
<ItemGroup>
<Compile Include="Dto.fs" />
<Compile Include="GeneratedDto.fs">
<WhippetFile>Dto.fs</WhippetFile>
<WhippetParamInnerType>JsonParse</WhippetParamInnerType>
<WhippetParamJsonRecordType>JsonParse(false)</WhippetParamJsonRecordType>
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="WoofWare.Whippet.Plugin.Json" WhippetPlugin="true" Version="" />
<PackageReference Include="WoofWare.Whippet" Version="" PrivateAssets="all" />
</ItemGroup>
</Project>
(This plugin follows a standard convention taken by WoofWare.Whippet.Plugin
plugins,
where you use Whippet parameters with the same name as each input type,
whose contents are a !
-delimited list of the generators which you wish to apply to that input type.)
Usage: JsonSerialize
Define a Dto.fs
file like the following:
namespace MyNamespace
open WoofWare.Whippet.Plugin.Json
[<JsonSerialize true>]
type InnerTypeWithBoth =
{
[<JsonPropertyName("it's-a-me")>]
Thing : string
ReadOnlyDict : IReadOnlyDictionary<string, Uri list>
}
In your fsproj:
<Project>
<ItemGroup>
<Compile Include="Dto.fs" />
<Compile Include="GeneratedDto.fs">
<WhippetFile>Dto.fs</WhippetFile>
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="WoofWare.Whippet.Plugin.Json.Attributes" Version="" />
<PackageReference Include="WoofWare.Whippet.Plugin.Json" WhippetPlugin="true" Version="" />
<PackageReference Include="WoofWare.Whippet" Version="" PrivateAssets="all" />
</ItemGroup>
</Project>
The generator will produce a file somewhat like the following:
namespace UsePlugin
/// Module containing JSON parsing methods for the JsonRecordType type
[<AutoOpen>]
module JsonRecordTypeExtension =
type InnerTypeWithBoth with
let toJsonNode (input : InnerTypeWithBoth) : System.Text.Json.Nodes.JsonNode =
let node = System.Text.Json.Nodes.JsonObject ()
do
node.Add (("it's-a-me"), System.Text.Json.Nodes.JsonValue.Create<string> input.Thing)
node.Add (
"ReadOnlyDict",
(fun field ->
let ret = System.Text.Json.Nodes.JsonObject ()
for (KeyValue (key, value)) in field do
ret.Add (key.ToString (), System.Text.Json.Nodes.JsonValue.Create<Uri> value)
ret
) input.Map
)
node
You may instead choose to define attributes with the correct name yourself (if you don't want to take a dependency on the WoofWare.Whippet.Plugin.Json.Attributes
package).
Alternatively, you may omit the attributes and the runtime dependency, and control the generator entirely through the fsproj file:
<Project>
<ItemGroup>
<Compile Include="Dto.fs" />
<Compile Include="GeneratedDto.fs">
<WhippetFile>Dto.fs</WhippetFile>
<WhippetParamInnerType>JsonSerialize</WhippetParamInnerType>
<WhippetParamJsonRecordType>JsonSerialize(false)</WhippetParamJsonRecordType>
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="WoofWare.Whippet.Plugin.Json" WhippetPlugin="true" Version="" />
<PackageReference Include="WoofWare.Whippet" Version="" PrivateAssets="all" />
</ItemGroup>
</Project>
(This plugin follows a standard convention taken by WoofWare.Whippet.Plugin
plugins,
where you use Whippet parameters with the same name as each input type,
whose contents are a !
-delimited list of the generators which you wish to apply to that input type.)
Notes
- The plugin includes an opinionated de/serializer for discriminated unions. (Any such serializer must be opinionated, because JSON does not natively model DUs.)
- Supply the optional boolean arg
false
to the[<JsonParse>]
/[<JsonSerialize>]
attributes, or pass it via<WhippetParamMyType>JsonParse(false)</WhippetParamMyType>
, to get a genuine module that can be consumed from C#.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- FSharp.Core (>= 6.0.1)
- WoofWare.Whippet.Core (>= 0.1.2)
- WoofWare.Whippet.Fantomas (>= 0.3.1)
- WoofWare.Whippet.Plugin.Json.Attributes (>= 0.2.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on WoofWare.Whippet.Plugin.Json:
Package | Downloads |
---|---|
WoofWare.Whippet.Plugin.HttpClient
Whippet F# source generator plugin, for generating RestEase-style HTTP clients. |
GitHub repositories
This package is not used by any popular GitHub repositories.