Compare commits

...

40 Commits

Author SHA1 Message Date
Patrick Stevens
569b3cc553 Pull out general changes from ArgParser PR (#217) 2024-08-25 19:23:23 +00:00
patrick-conscriptus[bot]
20226b9da9 Automated commit (#215)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-08-25 01:17:27 +00:00
dependabot[bot]
f800e53bff Bump ApiSurface from 4.0.43 to 4.0.44 (#214)
* Bump ApiSurface from 4.0.43 to 4.0.44

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) from 4.0.43 to 4.0.44.
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.0.43...ApiSurface.4.0.44)

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fix deps

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Smaug123 <3138005+Smaug123@users.noreply.github.com>
2024-08-19 20:22:38 +01:00
patrick-conscriptus[bot]
5358f5da0e Automated commit (#213)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-08-18 08:29:45 +00:00
Patrick Stevens
a868b8c08e No-op change to test the pipeline (#212) 2024-08-13 22:06:54 +00:00
Patrick Stevens
a4f945a3ee Upgrade all-required-checks-complete (#211) 2024-08-13 23:03:27 +01:00
Patrick Stevens
8434730ba7 Migrate to dedicated publish action (#210) 2024-08-13 21:54:14 +00:00
dependabot[bot]
811026996c Bump fsharp-analyzers from 0.26.0 to 0.26.1 (#208)
* Bump Nerdbank.GitVersioning from 3.6.139 to 3.6.141

Bumps [Nerdbank.GitVersioning](https://github.com/dotnet/Nerdbank.GitVersioning) from 3.6.139 to 3.6.141.
- [Release notes](https://github.com/dotnet/Nerdbank.GitVersioning/releases)
- [Commits](https://github.com/dotnet/Nerdbank.GitVersioning/compare/v3.6.139...v3.6.141)

---
updated-dependencies:
- dependency-name: Nerdbank.GitVersioning
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump fsharp-analyzers from 0.26.0 to 0.26.1

Bumps [fsharp-analyzers](https://github.com/ionide/FSharp.Analyzers.SDK) from 0.26.0 to 0.26.1.
- [Release notes](https://github.com/ionide/FSharp.Analyzers.SDK/releases)
- [Changelog](https://github.com/ionide/FSharp.Analyzers.SDK/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ionide/FSharp.Analyzers.SDK/compare/v0.26.0...v0.26.1)

---
updated-dependencies:
- dependency-name: fsharp-analyzers
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump deps

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Smaug123 <3138005+Smaug123@users.noreply.github.com>
2024-08-12 11:35:03 +00:00
dependabot[bot]
25b2b160bb Bump actions/attest-build-provenance from 1.4.0 to 1.4.1 (#206) 2024-08-12 11:27:09 +01:00
patrick-conscriptus[bot]
4679474604 Automated commit (#205)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-08-11 01:16:52 +00:00
dependabot[bot]
e16e241785 Bump actions/attest-build-provenance from 1.3.3 to 1.4.0 (#204) 2024-08-05 13:01:06 +01:00
Patrick Stevens
a52e4a46b0 Properly exclude test project (#203) 2024-08-04 19:42:15 +01:00
dependabot[bot]
f40a368948 Bump NUnit3TestAdapter from 4.5.0 to 4.6.0 (#201)
* Bump NUnit3TestAdapter from 4.5.0 to 4.6.0

Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 4.5.0 to 4.6.0.
- [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases)
- [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V4.5.0...V4.6.0)

---
updated-dependencies:
- dependency-name: NUnit3TestAdapter
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Smaug123 <3138005+Smaug123@users.noreply.github.com>
2024-08-04 19:07:03 +01:00
patrick-conscriptus[bot]
adaee61fbf Automated commit (#202)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-08-04 01:15:45 +00:00
patrick-conscriptus[bot]
d388660bfe Automated commit (#200)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-07-28 01:14:36 +00:00
patrick-conscriptus[bot]
d0e9ba0efd Automated commit (#199)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-07-21 01:14:26 +00:00
dependabot[bot]
d7d6c57910 Bump fantomas from 6.3.9 to 6.3.10 (#198)
Bumps fantomas from 6.3.9 to 6.3.10.

---
updated-dependencies:
- dependency-name: fantomas
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-15 17:44:58 +00:00
dependabot[bot]
98e52743f5 Bump actions/attest-build-provenance from 1.3.2 to 1.3.3 (#197) 2024-07-15 11:45:54 +01:00
patrick-conscriptus[bot]
896696e002 Automated commit (#196)
Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
2024-07-14 01:14:38 +00:00
Patrick Stevens
654f760f3a Abstract away the required-checks feature (#194) 2024-07-12 20:02:04 +00:00
Patrick Stevens
31bd9e22f2 Shrink flake-updating action (#193) 2024-07-12 19:44:13 +01:00
Patrick Stevens
b7a240bbb9 Early out of flake update if there are no changes (#192) 2024-07-12 16:46:04 +00:00
Patrick Stevens
ebbe10ad81 Fix PR-raising logic (#191) 2024-07-12 16:36:56 +00:00
patrick-conscriptus[bot]
8f9af9af67 Upgrade Nix flake and deps (#190)
* Automated commit

---------

Co-authored-by: patrick-conscriptus[bot] <175414948+patrick-conscriptus[bot]@users.noreply.github.com>
Co-authored-by: Smaug123 <3138005+Smaug123@users.noreply.github.com>
2024-07-12 16:32:21 +00:00
Patrick Stevens
2c7cd91cbc Fix default branch name bit of update workflow (#189) 2024-07-12 16:22:07 +00:00
Patrick Stevens
ffaa373da9 Fix flake update workflow (#184) 2024-07-12 16:07:31 +00:00
Patrick Stevens
9f8459a7d3 Add flake update workflow (#183) 2024-07-12 12:12:44 +01:00
Patrick Stevens
362542d5ee Make required status check actually required (#182) 2024-07-12 11:59:42 +01:00
Patrick Stevens
18309becbd Add reproducibility check (#181) 2024-07-11 00:39:31 +01:00
dependabot[bot]
e96803e303 Bump ApiSurface from 4.0.42 to 4.0.43 (#180)
* Bump ApiSurface from 4.0.42 to 4.0.43

Bumps ApiSurface from 4.0.42 to 4.0.43.

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Deps

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Smaug123 <3138005+Smaug123@users.noreply.github.com>
2024-07-08 19:06:18 +01:00
dependabot[bot]
b53b410feb Bump ApiSurface from 4.0.41 to 4.0.42 (#176)
* Bump ApiSurface from 4.0.41 to 4.0.42

Bumps [ApiSurface](https://github.com/G-Research/ApiSurface) from 4.0.41 to 4.0.42.
- [Release notes](https://github.com/G-Research/ApiSurface/releases)
- [Commits](https://github.com/G-Research/ApiSurface/compare/ApiSurface.4.0.41...ApiSurface.4.0.42)

---
updated-dependencies:
- dependency-name: ApiSurface
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Deps

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Smaug123 <3138005+Smaug123@users.noreply.github.com>
2024-07-01 18:21:26 +01:00
Patrick Stevens
398cd04a2a Support DateTimeOffset in JSON generators (#179) 2024-07-01 18:08:09 +01:00
Patrick Stevens
434c042510 Omit upcasts where possible (#178) 2024-07-01 17:45:36 +01:00
Patrick Stevens
c590db2a65 JSON enums (#175) 2024-06-27 21:23:06 +01:00
Patrick Stevens
6a81513a93 Add nullable support to JSON generators (#174) 2024-06-27 08:40:58 +01:00
Patrick Stevens
ba31689145 Also allow serialising units of measure (#171) 2024-06-25 00:04:56 +01:00
Patrick Stevens
85929d49d5 Support units of measure in JsonParse (#170) 2024-06-24 23:23:23 +01:00
dependabot[bot]
db4694f6e7 Bump actions/attest-build-provenance from 1.0.0 to 1.3.2 (#169)
Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 1.0.0 to 1.3.2.
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](897ed5eab6...bdd51370e0)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-24 18:55:05 +01:00
Patrick Stevens
669eccbdef Nudge README to bump the pipeline (#168) 2024-06-17 23:17:34 +01:00
Patrick Stevens
1bb87e55da Attest contents of packages (#167) 2024-06-17 23:08:36 +01:00
46 changed files with 1813 additions and 555 deletions

View File

@@ -3,13 +3,13 @@
"isRoot": true, "isRoot": true,
"tools": { "tools": {
"fantomas": { "fantomas": {
"version": "6.3.9", "version": "6.3.10",
"commands": [ "commands": [
"fantomas" "fantomas"
] ]
}, },
"fsharp-analyzers": { "fsharp-analyzers": {
"version": "0.26.0", "version": "0.26.1",
"commands": [ "commands": [
"fsharp-analyzers" "fsharp-analyzers"
] ]

View File

@@ -73,6 +73,8 @@ jobs:
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Build - name: Build
run: nix build run: nix build
- name: Reproducibility check
run: nix build --rebuild
check-dotnet-format: check-dotnet-format:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -217,15 +219,60 @@ jobs:
all-required-checks-complete: all-required-checks-complete:
needs: [check-dotnet-format, check-nix-format, check-accurate-generations, build, build-nix, linkcheck, flake-check, analyzers, nuget-pack, expected-pack, github-release-plugin-dry-run] needs: [check-dotnet-format, check-nix-format, check-accurate-generations, build, build-nix, linkcheck, flake-check, analyzers, nuget-pack, expected-pack, github-release-plugin-dry-run]
if: ${{ always() }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- run: echo "All required checks complete." - uses: Smaug123/all-required-checks-complete-action@d0ef051668d922e3591cc7c97156702946437f8d
with:
needs-context: ${{ toJSON(needs) }}
nuget-publish: attestation-attribute:
runs-on: ubuntu-latest
needs: [all-required-checks-complete]
if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }}
permissions:
id-token: write
attestations: write
contents: read
steps:
- name: Download NuGet artifact
uses: actions/download-artifact@v4
with:
name: nuget-package-attribute
path: packed
- name: Attest Build Provenance
uses: actions/attest-build-provenance@310b0a4a3b0b78ef57ecda988ee04b132db73ef8 # v1.4.1
with:
subject-path: "packed/*.nupkg"
attestation-plugin:
runs-on: ubuntu-latest
needs: [all-required-checks-complete]
if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }}
permissions:
id-token: write
attestations: write
contents: read
steps:
- name: Download NuGet artifact
uses: actions/download-artifact@v4
with:
name: nuget-package-plugin
path: packed
- name: Attest Build Provenance
uses: actions/attest-build-provenance@310b0a4a3b0b78ef57ecda988ee04b132db73ef8 # v1.4.1
with:
subject-path: "packed/*.nupkg"
nuget-publish-attribute:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }} if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }}
needs: [all-required-checks-complete] needs: [all-required-checks-complete]
environment: main-deploy environment: main-deploy
permissions:
id-token: write
attestations: write
contents: read
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install Nix - name: Install Nix
@@ -233,20 +280,55 @@ jobs:
with: with:
extra_nix_config: | extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Download NuGet artifact (plugin) - name: Download NuGet artifact
uses: actions/download-artifact@v4
with:
name: nuget-package-plugin
path: packed-plugin
- name: Publish to NuGet (plugin)
run: nix develop --command dotnet nuget push "packed-plugin/WoofWare.Myriad.Plugins.*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
- name: Download NuGet artifact (attribute)
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: nuget-package-attribute name: nuget-package-attribute
path: packed-attribute path: packed
- name: Publish to NuGet (attribute) - name: Identify `dotnet`
run: nix develop --command dotnet nuget push "packed-attribute/WoofWare.Myriad.Plugins.Attributes.*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate id: dotnet-identify
run: nix develop --command bash -c 'echo "dotnet=$(which dotnet)" >> $GITHUB_OUTPUT'
- name: Publish to NuGet
id: publish-success
uses: Smaug123/publish-nuget-action@76df889166633c2dc613560c092882aabe260df0
with:
package-name: WoofWare.Myriad.Plugins.Attributes
nuget-key: ${{ secrets.NUGET_API_KEY }}
nupkg-dir: packed/
dotnet: ${{ steps.dotnet-identify.outputs.dotnet }}
nuget-publish-plugin:
runs-on: ubuntu-latest
if: ${{ !github.event.repository.fork && github.ref == 'refs/heads/main' }}
needs: [all-required-checks-complete]
environment: main-deploy
permissions:
id-token: write
attestations: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@V27
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Download NuGet artifact
uses: actions/download-artifact@v4
with:
name: nuget-package-plugin
path: packed
- name: Identify `dotnet`
id: dotnet-identify
run: nix develop --command bash -c 'echo "dotnet=$(which dotnet)" >> $GITHUB_OUTPUT'
- name: Publish to NuGet
id: publish-success
uses: Smaug123/publish-nuget-action@76df889166633c2dc613560c092882aabe260df0
with:
package-name: WoofWare.Myriad.Plugins
nuget-key: ${{ secrets.NUGET_API_KEY }}
nupkg-dir: packed/
dotnet: ${{ steps.dotnet-identify.outputs.dotnet }}
github-release-plugin: github-release-plugin:
runs-on: ubuntu-latest runs-on: ubuntu-latest

57
.github/workflows/flake_update.yaml vendored Normal file
View File

@@ -0,0 +1,57 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/github-workflow.json
name: Weekly Nix Flake Update
on:
schedule:
- cron: '0 0 * * 0' # Runs at 00:00 every Sunday
workflow_dispatch: # Allows manual triggering
jobs:
update-nix-flake:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Update Nix flake
run: 'nix flake update'
- name: Build passthru
run: 'nix build ".#default.passthru.fetch-deps"'
- name: Run passthru
run: |
set -o pipefail
./result | tee /tmp/passthru.txt
cp /"$(cat /tmp/passthru.txt | grep " wrote lockfile to " | cut -d / -f 2-)" nix/deps.nix
- name: Format
run: 'nix develop --command alejandra .'
- name: Create token
id: generate-token
uses: actions/create-github-app-token@v1
with:
# https://github.com/actions/create-github-app-token/issues/136
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Raise pull request
uses: Smaug123/commit-action@cc25e6d80a796c49669dda4a0aa36c54c573983d
id: cpr
with:
bearer-token: ${{ steps.generate-token.outputs.token }}
pr-title: "Upgrade Nix flake and deps"
- name: Enable Pull Request Automerge
if: ${{ steps.cpr.outputs.pull-request-number }}
uses: peter-evans/enable-pull-request-automerge@v3
with:
token: ${{ steps.generate-token.outputs.token }}
pull-request-number: ${{ steps.cpr.outputs.pull-request-number }}
merge-method: squash

25
.gitignore vendored
View File

@@ -1,12 +1,13 @@
bin/ bin/
obj/ obj/
/packages/ /packages/
riderModule.iml riderModule.iml
/_ReSharper.Caches/ /_ReSharper.Caches/
.idea/ .idea/
*.sln.DotSettings.user *.sln.DotSettings.user
.DS_Store .DS_Store
result result
.analyzerpackages/ .analyzerpackages/
analysis.sarif analysis.sarif
.direnv/ .direnv/
.venv/

View File

@@ -1,5 +1,10 @@
Notable changes are recorded here. Notable changes are recorded here.
# WoofWare.Myriad.Plugins 2.1.45, WoofWare.Myriad.Plugins.Attributes 3.1.7
The NuGet packages are now attested to through [GitHub Attestations](https://github.blog/2024-05-02-introducing-artifact-attestations-now-in-public-beta/).
You can run `gh attestation verify ~/.nuget/packages/woofware.myriad.plugins/2.1.45/woofware.myriad.plugins.2.1.45.nupkg -o Smaug123`, for example, to verify with GitHub that the GitHub Actions pipeline on this repository produced a nupkg file with the same hash as the one you were served from NuGet.
# WoofWare.Myriad.Plugins 2.1.33 # WoofWare.Myriad.Plugins 2.1.33
`JsonParse` can now deserialize the discriminated unions which `JsonSerialize` wrote out. `JsonParse` can now deserialize the discriminated unions which `JsonSerialize` wrote out.

View File

@@ -3,6 +3,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<OtherFlags>--reflectionfree $(OtherFlags)</OtherFlags>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<MyriadSdkGenerator Include="$(MSBuildThisFileDirectory)..\WoofWare.Myriad.Plugins\bin\$(Configuration)\net6.0\WoofWare.Myriad.Plugins.dll"/> <MyriadSdkGenerator Include="$(MSBuildThisFileDirectory)..\WoofWare.Myriad.Plugins\bin\$(Configuration)\net6.0\WoofWare.Myriad.Plugins.dll"/>
@@ -56,9 +57,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="RestEase" Version="1.6.4"/> <PackageReference Include="RestEase" Version="1.6.4"/>
<ProjectReference Include="..\WoofWare.Myriad.Plugins.Attributes\WoofWare.Myriad.Plugins.Attributes.fsproj" /> <ProjectReference Include="..\WoofWare.Myriad.Plugins.Attributes\WoofWare.Myriad.Plugins.Attributes.fsproj" />
<ProjectReference Include="..\WoofWare.Myriad.Plugins\WoofWare.Myriad.Plugins.fsproj"/> <ProjectReference Include="..\WoofWare.Myriad.Plugins\WoofWare.Myriad.Plugins.fsproj" PrivateAssets="all" />
<PackageReference Include="Myriad.Sdk" Version="0.8.3"/> <PackageReference Include="Myriad.Sdk" Version="0.8.3" PrivateAssets="all" />
<PackageReference Include="Myriad.Core" Version="0.8.3"/>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -30,6 +30,12 @@ type ChocolateType =
| Milk | Milk
| SeventyPercent | SeventyPercent
override this.ToString () =
match this with
| ChocolateType.Dark -> "Dark"
| ChocolateType.Milk -> "Milk"
| ChocolateType.SeventyPercent -> "SeventyPercent"
type Chocolate = type Chocolate =
{ {
chocType : ChocolateType chocType : ChocolateType
@@ -43,6 +49,12 @@ type WrappingPaperStyle =
| HappyHolidays | HappyHolidays
| SolidColor | SolidColor
override this.ToString () =
match this with
| WrappingPaperStyle.HappyBirthday -> "HappyBirthday"
| WrappingPaperStyle.HappyHolidays -> "HappyHolidays"
| WrappingPaperStyle.SolidColor -> "SolidColor"
[<CreateCatamorphism "GiftCata">] [<CreateCatamorphism "GiftCata">]
type Gift = type Gift =
| Book of Book | Book of Book

View File

@@ -14,7 +14,7 @@ module internal InternalTypeNotExtensionSerial =
/// Serialize to a JSON node /// Serialize to a JSON node
let toJsonNode (input : InternalTypeNotExtensionSerial) : System.Text.Json.Nodes.JsonNode = let toJsonNode (input : InternalTypeNotExtensionSerial) : System.Text.Json.Nodes.JsonNode =
let node = System.Text.Json.Nodes.JsonObject () let node = System.Text.Json.Nodes.JsonObject ()
do node.Add ((Literals.something), System.Text.Json.Nodes.JsonValue.Create<string> input.InternalThing2) do node.Add ((Literals.something), (input.InternalThing2 |> System.Text.Json.Nodes.JsonValue.Create<string>))
node :> _ node :> _
namespace ConsumePlugin namespace ConsumePlugin
@@ -29,7 +29,7 @@ module internal InternalTypeExtensionJsonSerializeExtension =
/// Serialize to a JSON node /// Serialize to a JSON node
static member toJsonNode (input : InternalTypeExtension) : System.Text.Json.Nodes.JsonNode = static member toJsonNode (input : InternalTypeExtension) : System.Text.Json.Nodes.JsonNode =
let node = System.Text.Json.Nodes.JsonObject () let node = System.Text.Json.Nodes.JsonObject ()
do node.Add ((Literals.something), System.Text.Json.Nodes.JsonValue.Create<string> input.ExternalThing) do node.Add ((Literals.something), (input.ExternalThing |> System.Text.Json.Nodes.JsonValue.Create<string>))
node :> _ node :> _
namespace ConsumePlugin namespace ConsumePlugin
@@ -49,7 +49,7 @@ module InnerType =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
{ {
Thing = arg_0 Thing = arg_0
@@ -71,7 +71,7 @@ module JsonRecordType =
) )
| v -> v) | v -> v)
.AsArray () .AsArray ()
|> Seq.map (fun elt -> elt.AsValue().GetValue<int> ()) |> Seq.map (fun elt -> elt.AsValue().GetValue<System.Int32> ())
|> Array.ofSeq |> Array.ofSeq
let arg_4 = let arg_4 =
@@ -84,7 +84,7 @@ module JsonRecordType =
) )
| v -> v) | v -> v)
.AsArray () .AsArray ()
|> Seq.map (fun elt -> elt.AsValue().GetValue<string> ()) |> Seq.map (fun elt -> elt.AsValue().GetValue<System.String> ())
|> Array.ofSeq |> Array.ofSeq
let arg_3 = let arg_3 =
@@ -109,7 +109,7 @@ module JsonRecordType =
) )
| v -> v) | v -> v)
.AsArray () .AsArray ()
|> Seq.map (fun elt -> elt.AsValue().GetValue<int> ()) |> Seq.map (fun elt -> elt.AsValue().GetValue<System.Int32> ())
|> List.ofSeq |> List.ofSeq
let arg_1 = let arg_1 =
@@ -122,7 +122,7 @@ module JsonRecordType =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_0 = let arg_0 =
(match node.["a"] with (match node.["a"] with
@@ -134,7 +134,7 @@ module JsonRecordType =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
{ {
A = arg_0 A = arg_0
@@ -161,7 +161,7 @@ module internal InternalTypeNotExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
{ {
InternalThing = arg_0 InternalThing = arg_0
@@ -186,7 +186,7 @@ module internal InternalTypeExtensionJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
{ {
ExternalThing = arg_0 ExternalThing = arg_0
@@ -345,7 +345,7 @@ module ToGetExtensionMethodJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_7 = let arg_7 =
(match node.["hotel"] with (match node.["hotel"] with
@@ -417,7 +417,7 @@ module ToGetExtensionMethodJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<float> () .GetValue<System.Double> ()
let arg_1 = let arg_1 =
(match node.["bravo"] with (match node.["bravo"] with
@@ -442,7 +442,7 @@ module ToGetExtensionMethodJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
{ {
Alpha = arg_0 Alpha = arg_0

View File

@@ -20,21 +20,26 @@ module MemberJsonSerializeExtension =
let node = System.Text.Json.Nodes.JsonObject () let node = System.Text.Json.Nodes.JsonObject ()
do do
node.Add ("id", System.Text.Json.Nodes.JsonValue.Create<int> input.Id) node.Add ("id", (input.Id |> System.Text.Json.Nodes.JsonValue.Create<int>))
node.Add ("compoundMemberId", System.Text.Json.Nodes.JsonValue.Create<string> input.CompoundMemberId)
node.Add ("firstName", System.Text.Json.Nodes.JsonValue.Create<string> input.FirstName) node.Add (
node.Add ("lastName", System.Text.Json.Nodes.JsonValue.Create<string> input.LastName) "compoundMemberId",
node.Add ("homeGymId", System.Text.Json.Nodes.JsonValue.Create<int> input.HomeGymId) (input.CompoundMemberId |> System.Text.Json.Nodes.JsonValue.Create<string>)
node.Add ("homeGymName", System.Text.Json.Nodes.JsonValue.Create<string> input.HomeGymName) )
node.Add ("emailAddress", System.Text.Json.Nodes.JsonValue.Create<string> input.EmailAddress)
node.Add ("gymAccessPin", System.Text.Json.Nodes.JsonValue.Create<string> input.GymAccessPin) node.Add ("firstName", (input.FirstName |> System.Text.Json.Nodes.JsonValue.Create<string>))
node.Add ("dateofBirth", System.Text.Json.Nodes.JsonValue.Create<DateOnly> input.DateOfBirth) node.Add ("lastName", (input.LastName |> System.Text.Json.Nodes.JsonValue.Create<string>))
node.Add ("mobileNumber", System.Text.Json.Nodes.JsonValue.Create<string> input.MobileNumber) node.Add ("homeGymId", (input.HomeGymId |> System.Text.Json.Nodes.JsonValue.Create<int>))
node.Add ("postCode", System.Text.Json.Nodes.JsonValue.Create<string> input.Postcode) node.Add ("homeGymName", (input.HomeGymName |> System.Text.Json.Nodes.JsonValue.Create<string>))
node.Add ("membershipName", System.Text.Json.Nodes.JsonValue.Create<string> input.MembershipName) node.Add ("emailAddress", (input.EmailAddress |> System.Text.Json.Nodes.JsonValue.Create<string>))
node.Add ("membershipLevel", System.Text.Json.Nodes.JsonValue.Create<int> input.MembershipLevel) node.Add ("gymAccessPin", (input.GymAccessPin |> System.Text.Json.Nodes.JsonValue.Create<string>))
node.Add ("suspendedReason", System.Text.Json.Nodes.JsonValue.Create<int> input.SuspendedReason) node.Add ("dateofBirth", (input.DateOfBirth |> System.Text.Json.Nodes.JsonValue.Create<DateOnly>))
node.Add ("memberStatus", System.Text.Json.Nodes.JsonValue.Create<int> input.MemberStatus) node.Add ("mobileNumber", (input.MobileNumber |> System.Text.Json.Nodes.JsonValue.Create<string>))
node.Add ("postCode", (input.Postcode |> System.Text.Json.Nodes.JsonValue.Create<string>))
node.Add ("membershipName", (input.MembershipName |> System.Text.Json.Nodes.JsonValue.Create<string>))
node.Add ("membershipLevel", (input.MembershipLevel |> System.Text.Json.Nodes.JsonValue.Create<int>))
node.Add ("suspendedReason", (input.SuspendedReason |> System.Text.Json.Nodes.JsonValue.Create<int>))
node.Add ("memberStatus", (input.MemberStatus |> System.Text.Json.Nodes.JsonValue.Create<int>))
node :> _ node :> _
@@ -55,7 +60,7 @@ module GymOpeningHours =
) )
| v -> v) | v -> v)
.AsArray () .AsArray ()
|> Seq.map (fun elt -> elt.AsValue().GetValue<string> ()) |> Seq.map (fun elt -> elt.AsValue().GetValue<System.String> ())
|> List.ofSeq |> List.ofSeq
let arg_0 = let arg_0 =
@@ -68,7 +73,7 @@ module GymOpeningHours =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<bool> () .GetValue<System.Boolean> ()
{ {
IsAlwaysOpen = arg_0 IsAlwaysOpen = arg_0
@@ -91,7 +96,7 @@ module GymAccessOptions =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<bool> () .GetValue<System.Boolean> ()
let arg_0 = let arg_0 =
(match node.["pinAccess"] with (match node.["pinAccess"] with
@@ -103,7 +108,7 @@ module GymAccessOptions =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<bool> () .GetValue<System.Boolean> ()
{ {
PinAccess = arg_0 PinAccess = arg_0
@@ -127,7 +132,7 @@ module GymLocation =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<float> () .GetValue<System.Double> ()
with :? System.InvalidOperationException as exc -> with :? System.InvalidOperationException as exc ->
if exc.Message.Contains "cannot be converted to" then if exc.Message.Contains "cannot be converted to" then
if if
@@ -148,6 +153,7 @@ module GymLocation =
reraise () reraise ()
else else
reraise () reraise ()
|> LanguagePrimitives.FloatWithMeasure
let arg_0 = let arg_0 =
try try
@@ -160,7 +166,7 @@ module GymLocation =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<float> () .GetValue<System.Double> ()
with :? System.InvalidOperationException as exc -> with :? System.InvalidOperationException as exc ->
if exc.Message.Contains "cannot be converted to" then if exc.Message.Contains "cannot be converted to" then
if if
@@ -203,12 +209,12 @@ module GymAddress =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_4 = let arg_4 =
match node.["county"] with match node.["county"] with
| null -> None | null -> None
| v -> v.AsValue().GetValue<string> () |> Some | v -> v.AsValue().GetValue<System.String> () |> Some
let arg_3 = let arg_3 =
(match node.["town"] with (match node.["town"] with
@@ -220,17 +226,17 @@ module GymAddress =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_2 = let arg_2 =
match node.["addressLine3"] with match node.["addressLine3"] with
| null -> None | null -> None
| v -> v.AsValue().GetValue<string> () |> Some | v -> v.AsValue().GetValue<System.String> () |> Some
let arg_1 = let arg_1 =
match node.["addressLine2"] with match node.["addressLine2"] with
| null -> None | null -> None
| v -> v.AsValue().GetValue<string> () |> Some | v -> v.AsValue().GetValue<System.String> () |> Some
let arg_0 = let arg_0 =
(match node.["addressLine1"] with (match node.["addressLine1"] with
@@ -242,7 +248,7 @@ module GymAddress =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
{ {
AddressLine1 = arg_0 AddressLine1 = arg_0
@@ -269,7 +275,7 @@ module Gym =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_9 = let arg_9 =
(match node.["timeZone"] with (match node.["timeZone"] with
@@ -281,7 +287,7 @@ module Gym =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_8 = let arg_8 =
GymLocation.jsonParse ( GymLocation.jsonParse (
@@ -329,7 +335,7 @@ module Gym =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_4 = let arg_4 =
(match node.["phoneNumber"] with (match node.["phoneNumber"] with
@@ -341,7 +347,7 @@ module Gym =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_3 = let arg_3 =
GymAddress.jsonParse ( GymAddress.jsonParse (
@@ -365,7 +371,7 @@ module Gym =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_1 = let arg_1 =
(match node.["id"] with (match node.["id"] with
@@ -377,7 +383,7 @@ module Gym =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_0 = let arg_0 =
(match node.["name"] with (match node.["name"] with
@@ -389,7 +395,7 @@ module Gym =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
{ {
Name = arg_0 Name = arg_0
@@ -424,7 +430,7 @@ module MemberJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_13 = let arg_13 =
(match node.["suspendedReason"] with (match node.["suspendedReason"] with
@@ -436,7 +442,7 @@ module MemberJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_12 = let arg_12 =
(match node.["membershipLevel"] with (match node.["membershipLevel"] with
@@ -448,7 +454,7 @@ module MemberJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_11 = let arg_11 =
(match node.["membershipName"] with (match node.["membershipName"] with
@@ -460,7 +466,7 @@ module MemberJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_10 = let arg_10 =
(match node.["postCode"] with (match node.["postCode"] with
@@ -472,7 +478,7 @@ module MemberJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_9 = let arg_9 =
(match node.["mobileNumber"] with (match node.["mobileNumber"] with
@@ -484,7 +490,7 @@ module MemberJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_8 = let arg_8 =
(match node.["dateofBirth"] with (match node.["dateofBirth"] with
@@ -509,7 +515,7 @@ module MemberJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_6 = let arg_6 =
(match node.["emailAddress"] with (match node.["emailAddress"] with
@@ -521,7 +527,7 @@ module MemberJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_5 = let arg_5 =
(match node.["homeGymName"] with (match node.["homeGymName"] with
@@ -533,7 +539,7 @@ module MemberJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_4 = let arg_4 =
(match node.["homeGymId"] with (match node.["homeGymId"] with
@@ -545,7 +551,7 @@ module MemberJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_3 = let arg_3 =
(match node.["lastName"] with (match node.["lastName"] with
@@ -557,7 +563,7 @@ module MemberJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_2 = let arg_2 =
(match node.["firstName"] with (match node.["firstName"] with
@@ -569,7 +575,7 @@ module MemberJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_1 = let arg_1 =
(match node.["compoundMemberId"] with (match node.["compoundMemberId"] with
@@ -581,7 +587,7 @@ module MemberJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_0 = let arg_0 =
(match node.["id"] with (match node.["id"] with
@@ -593,7 +599,7 @@ module MemberJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
{ {
Id = arg_0 Id = arg_0
@@ -629,7 +635,7 @@ module GymAttendance =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_7 = let arg_7 =
(match node.["lastRefreshedPeopleInClasses"] with (match node.["lastRefreshedPeopleInClasses"] with
@@ -680,12 +686,12 @@ module GymAttendance =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<bool> () .GetValue<System.Boolean> ()
let arg_3 = let arg_3 =
match node.["totalPeopleSuffix"] with match node.["totalPeopleSuffix"] with
| null -> None | null -> None
| v -> v.AsValue().GetValue<string> () |> Some | v -> v.AsValue().GetValue<System.String> () |> Some
let arg_2 = let arg_2 =
(match node.["totalPeopleInClasses"] with (match node.["totalPeopleInClasses"] with
@@ -697,7 +703,7 @@ module GymAttendance =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_1 = let arg_1 =
(match node.["totalPeopleInGym"] with (match node.["totalPeopleInGym"] with
@@ -709,7 +715,7 @@ module GymAttendance =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_0 = let arg_0 =
(match node.["description"] with (match node.["description"] with
@@ -721,7 +727,7 @@ module GymAttendance =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
{ {
Description = arg_0 Description = arg_0
@@ -764,7 +770,7 @@ module MemberActivityDto =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<bool> () .GetValue<System.Boolean> ()
let arg_3 = let arg_3 =
(match node.["totalClasses"] with (match node.["totalClasses"] with
@@ -776,7 +782,7 @@ module MemberActivityDto =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_2 = let arg_2 =
(match node.["totalVisits"] with (match node.["totalVisits"] with
@@ -788,7 +794,7 @@ module MemberActivityDto =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_1 = let arg_1 =
(match node.["averageDuration"] with (match node.["averageDuration"] with
@@ -800,7 +806,7 @@ module MemberActivityDto =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_0 = let arg_0 =
(match node.["totalDuration"] with (match node.["totalDuration"] with
@@ -812,7 +818,7 @@ module MemberActivityDto =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
{ {
TotalDuration = arg_0 TotalDuration = arg_0
@@ -839,7 +845,7 @@ module SessionsAggregate =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_1 = let arg_1 =
(match node.["Visits"] with (match node.["Visits"] with
@@ -851,7 +857,7 @@ module SessionsAggregate =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_0 = let arg_0 =
(match node.["Activities"] with (match node.["Activities"] with
@@ -863,7 +869,7 @@ module SessionsAggregate =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
{ {
Activities = arg_0 Activities = arg_0
@@ -887,7 +893,7 @@ module VisitGym =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_1 = let arg_1 =
(match node.["Name"] with (match node.["Name"] with
@@ -899,7 +905,7 @@ module VisitGym =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_0 = let arg_0 =
(match node.["Id"] with (match node.["Id"] with
@@ -911,7 +917,7 @@ module VisitGym =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
{ {
Id = arg_0 Id = arg_0
@@ -947,7 +953,7 @@ module Visit =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_1 = let arg_1 =
(match node.["StartTime"] with (match node.["StartTime"] with
@@ -972,7 +978,7 @@ module Visit =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<bool> () .GetValue<System.Boolean> ()
{ {
IsDurationEstimated = arg_0 IsDurationEstimated = arg_0

View File

@@ -302,7 +302,7 @@ module PureGymApi =
v.AsObject () v.AsObject ()
|> Seq.map (fun kvp -> |> Seq.map (fun kvp ->
let key = (kvp.Key) let key = (kvp.Key)
let value = (kvp.Value).AsValue().GetValue<string> () let value = (kvp.Value).AsValue().GetValue<System.String> ()
key, value key, value
) )
|> Map.ofSeq |> Map.ofSeq

View File

@@ -21,69 +21,69 @@ module InnerTypeWithBothJsonSerializeExtension =
let node = System.Text.Json.Nodes.JsonObject () let node = System.Text.Json.Nodes.JsonObject ()
do do
node.Add (("it's-a-me"), System.Text.Json.Nodes.JsonValue.Create<Guid> input.Thing) node.Add (("it's-a-me"), (input.Thing |> System.Text.Json.Nodes.JsonValue.Create<Guid>))
node.Add ( node.Add (
"map", "map",
(fun field -> (input.Map
let ret = System.Text.Json.Nodes.JsonObject () |> (fun field ->
let ret = System.Text.Json.Nodes.JsonObject ()
for (KeyValue (key, value)) in field do for (KeyValue (key, value)) in field do
ret.Add (key.ToString (), System.Text.Json.Nodes.JsonValue.Create<Uri> value) ret.Add (key.ToString (), System.Text.Json.Nodes.JsonValue.Create<Uri> value)
ret ret
) ))
input.Map
) )
node.Add ( node.Add (
"readOnlyDict", "readOnlyDict",
(fun field -> (input.ReadOnlyDict
let ret = System.Text.Json.Nodes.JsonObject () |> (fun field ->
let ret = System.Text.Json.Nodes.JsonObject ()
for (KeyValue (key, value)) in field do for (KeyValue (key, value)) in field do
ret.Add ( ret.Add (
key.ToString (), key.ToString (),
(fun field -> (fun field ->
let arr = System.Text.Json.Nodes.JsonArray () let arr = System.Text.Json.Nodes.JsonArray ()
for mem in field do for mem in field do
arr.Add (System.Text.Json.Nodes.JsonValue.Create<char> mem) arr.Add (System.Text.Json.Nodes.JsonValue.Create<char> mem)
arr arr
) )
value value
) )
ret ret
) ))
input.ReadOnlyDict
) )
node.Add ( node.Add (
"dict", "dict",
(fun field -> (input.Dict
let ret = System.Text.Json.Nodes.JsonObject () |> (fun field ->
let ret = System.Text.Json.Nodes.JsonObject ()
for (KeyValue (key, value)) in field do for (KeyValue (key, value)) in field do
ret.Add (key.ToString (), System.Text.Json.Nodes.JsonValue.Create<bool> value) ret.Add (key.ToString (), System.Text.Json.Nodes.JsonValue.Create<bool> value)
ret ret
) ))
input.Dict
) )
node.Add ( node.Add (
"concreteDict", "concreteDict",
(fun field -> (input.ConcreteDict
let ret = System.Text.Json.Nodes.JsonObject () |> (fun field ->
let ret = System.Text.Json.Nodes.JsonObject ()
for (KeyValue (key, value)) in field do for (KeyValue (key, value)) in field do
ret.Add (key.ToString (), InnerTypeWithBoth.toJsonNode value) ret.Add (key.ToString (), InnerTypeWithBoth.toJsonNode value)
ret ret
) ))
input.ConcreteDict
) )
node :> _ node :> _
@@ -93,6 +93,24 @@ open System
open System.Collections.Generic open System.Collections.Generic
open System.Text.Json.Serialization open System.Text.Json.Serialization
/// Module containing JSON serializing extension members for the SomeEnum type
[<AutoOpen>]
module SomeEnumJsonSerializeExtension =
/// Extension methods for JSON parsing
type SomeEnum with
/// Serialize to a JSON node
static member toJsonNode (input : SomeEnum) : System.Text.Json.Nodes.JsonNode =
match input with
| SomeEnum.Blah -> System.Text.Json.Nodes.JsonValue.Create 1
| SomeEnum.Thing -> System.Text.Json.Nodes.JsonValue.Create 0
| v -> failwith (sprintf "Unrecognised value for enum: %O" v)
namespace ConsumePlugin
open System
open System.Collections.Generic
open System.Text.Json.Serialization
/// Module containing JSON serializing extension members for the JsonRecordTypeWithBoth type /// Module containing JSON serializing extension members for the JsonRecordTypeWithBoth type
[<AutoOpen>] [<AutoOpen>]
module JsonRecordTypeWithBothJsonSerializeExtension = module JsonRecordTypeWithBothJsonSerializeExtension =
@@ -104,48 +122,92 @@ module JsonRecordTypeWithBothJsonSerializeExtension =
let node = System.Text.Json.Nodes.JsonObject () let node = System.Text.Json.Nodes.JsonObject ()
do do
node.Add ("a", System.Text.Json.Nodes.JsonValue.Create<int> input.A) node.Add ("a", (input.A |> System.Text.Json.Nodes.JsonValue.Create<int>))
node.Add ("b", System.Text.Json.Nodes.JsonValue.Create<string> input.B) node.Add ("b", (input.B |> System.Text.Json.Nodes.JsonValue.Create<string>))
node.Add ( node.Add (
"c", "c",
(fun field -> (input.C
let arr = System.Text.Json.Nodes.JsonArray () |> (fun field ->
let arr = System.Text.Json.Nodes.JsonArray ()
for mem in field do for mem in field do
arr.Add (System.Text.Json.Nodes.JsonValue.Create<int> mem) arr.Add (System.Text.Json.Nodes.JsonValue.Create<int> mem)
arr arr
) ))
input.C
) )
node.Add ("d", InnerTypeWithBoth.toJsonNode input.D) node.Add ("d", (input.D |> InnerTypeWithBoth.toJsonNode))
node.Add ( node.Add (
"e", "e",
(fun field -> (input.E
let arr = System.Text.Json.Nodes.JsonArray () |> (fun field ->
let arr = System.Text.Json.Nodes.JsonArray ()
for mem in field do for mem in field do
arr.Add (System.Text.Json.Nodes.JsonValue.Create<string> mem) arr.Add (System.Text.Json.Nodes.JsonValue.Create<string> mem)
arr arr
) ))
input.E
) )
node.Add ( node.Add (
"f", "arr",
(fun field -> (input.Arr
let arr = System.Text.Json.Nodes.JsonArray () |> (fun field ->
let arr = System.Text.Json.Nodes.JsonArray ()
for mem in field do for mem in field do
arr.Add (System.Text.Json.Nodes.JsonValue.Create<int> mem) arr.Add (System.Text.Json.Nodes.JsonValue.Create<int> mem)
arr arr
) ))
input.F )
node.Add ("byte", (input.Byte |> System.Text.Json.Nodes.JsonValue.Create<byte<measure>>))
node.Add ("sbyte", (input.Sbyte |> System.Text.Json.Nodes.JsonValue.Create<sbyte<measure>>))
node.Add ("i", (input.I |> System.Text.Json.Nodes.JsonValue.Create<int<measure>>))
node.Add ("i32", (input.I32 |> System.Text.Json.Nodes.JsonValue.Create<int32<measure>>))
node.Add ("i64", (input.I64 |> System.Text.Json.Nodes.JsonValue.Create<int64<measure>>))
node.Add ("u", (input.U |> System.Text.Json.Nodes.JsonValue.Create<uint<measure>>))
node.Add ("u32", (input.U32 |> System.Text.Json.Nodes.JsonValue.Create<uint32<measure>>))
node.Add ("u64", (input.U64 |> System.Text.Json.Nodes.JsonValue.Create<uint64<measure>>))
node.Add ("f", (input.F |> System.Text.Json.Nodes.JsonValue.Create<float<measure>>))
node.Add ("f32", (input.F32 |> System.Text.Json.Nodes.JsonValue.Create<float32<measure>>))
node.Add ("single", (input.Single |> System.Text.Json.Nodes.JsonValue.Create<single<measure>>))
node.Add (
"intMeasureOption",
(input.IntMeasureOption
|> (fun field ->
match field with
| None -> null :> System.Text.Json.Nodes.JsonNode
| Some field ->
(System.Text.Json.Nodes.JsonValue.Create<int<measure>> field)
:> System.Text.Json.Nodes.JsonNode
))
)
node.Add (
"intMeasureNullable",
(input.IntMeasureNullable
|> (fun field ->
if field.HasValue then
System.Text.Json.Nodes.JsonValue.Create<int<measure>> field.Value
:> System.Text.Json.Nodes.JsonNode
else
null :> System.Text.Json.Nodes.JsonNode
))
)
node.Add ("enum", (input.Enum |> SomeEnum.toJsonNode))
node.Add (
"timestamp",
(input.Timestamp
|> (fun field -> field.ToString "o" |> System.Text.Json.Nodes.JsonValue.Create<string>))
) )
node :> _ node :> _
@@ -180,6 +242,55 @@ module FirstDuJsonSerializeExtension =
node.Add ("data", dataNode) node.Add ("data", dataNode)
node :> _ node :> _
namespace ConsumePlugin
open System
open System.Collections.Generic
open System.Text.Json.Serialization
/// Module containing JSON serializing extension members for the HeaderAndValue type
[<AutoOpen>]
module HeaderAndValueJsonSerializeExtension =
/// Extension methods for JSON parsing
type HeaderAndValue with
/// Serialize to a JSON node
static member toJsonNode (input : HeaderAndValue) : System.Text.Json.Nodes.JsonNode =
let node = System.Text.Json.Nodes.JsonObject ()
do
node.Add ("header", (input.Header |> System.Text.Json.Nodes.JsonValue.Create<string>))
node.Add ("value", (input.Value |> System.Text.Json.Nodes.JsonValue.Create<string>))
node :> _
namespace ConsumePlugin
open System
open System.Collections.Generic
open System.Text.Json.Serialization
/// Module containing JSON serializing extension members for the Foo type
[<AutoOpen>]
module FooJsonSerializeExtension =
/// Extension methods for JSON parsing
type Foo with
/// Serialize to a JSON node
static member toJsonNode (input : Foo) : System.Text.Json.Nodes.JsonNode =
let node = System.Text.Json.Nodes.JsonObject ()
do
node.Add (
"message",
(input.Message
|> (fun field ->
match field with
| None -> null :> System.Text.Json.Nodes.JsonNode
| Some field -> HeaderAndValue.toJsonNode field
))
)
node :> _
namespace ConsumePlugin namespace ConsumePlugin
@@ -221,7 +332,7 @@ module InnerTypeWithBothJsonParseExtension =
.AsObject () .AsObject ()
|> Seq.map (fun kvp -> |> Seq.map (fun kvp ->
let key = (kvp.Key) |> System.Uri let key = (kvp.Key) |> System.Uri
let value = (kvp.Value).AsValue().GetValue<bool> () let value = (kvp.Value).AsValue().GetValue<System.Boolean> ()
key, value key, value
) )
|> dict |> dict
@@ -287,6 +398,24 @@ module InnerTypeWithBothJsonParseExtension =
} }
namespace ConsumePlugin namespace ConsumePlugin
/// Module containing JSON parsing extension members for the SomeEnum type
[<AutoOpen>]
module SomeEnumJsonParseExtension =
/// Extension methods for JSON parsing
type SomeEnum with
/// Parse from a JSON node.
static member jsonParse (node : System.Text.Json.Nodes.JsonNode) : SomeEnum =
match node.GetValueKind () with
| System.Text.Json.JsonValueKind.Number -> node.AsValue().GetValue<int> () |> enum<SomeEnum>
| System.Text.Json.JsonValueKind.String ->
match node.AsValue().GetValue<string>().ToLowerInvariant () with
| "blah" -> SomeEnum.Blah
| "thing" -> SomeEnum.Thing
| v -> failwith ("Unrecognised value for enum: %i" + v)
| _ -> failwith ("Unrecognised kind for enum of type: " + "SomeEnum")
namespace ConsumePlugin
/// Module containing JSON parsing extension members for the JsonRecordTypeWithBoth type /// Module containing JSON parsing extension members for the JsonRecordTypeWithBoth type
[<AutoOpen>] [<AutoOpen>]
module JsonRecordTypeWithBothJsonParseExtension = module JsonRecordTypeWithBothJsonParseExtension =
@@ -295,7 +424,74 @@ module JsonRecordTypeWithBothJsonParseExtension =
/// Parse from a JSON node. /// Parse from a JSON node.
static member jsonParse (node : System.Text.Json.Nodes.JsonNode) : JsonRecordTypeWithBoth = static member jsonParse (node : System.Text.Json.Nodes.JsonNode) : JsonRecordTypeWithBoth =
let arg_5 = let arg_20 =
(match node.["timestamp"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("timestamp")
)
)
| v -> v)
.AsValue()
.GetValue<string> ()
|> System.DateTimeOffset.Parse
let arg_19 =
SomeEnum.jsonParse (
match node.["enum"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("enum")
)
)
| v -> v
)
let arg_18 =
match node.["intMeasureNullable"] with
| null -> System.Nullable ()
| v ->
v.AsValue().GetValue<System.Int32> ()
|> LanguagePrimitives.Int32WithMeasure
|> System.Nullable
let arg_17 =
match node.["intMeasureOption"] with
| null -> None
| v ->
v.AsValue().GetValue<System.Int32> ()
|> LanguagePrimitives.Int32WithMeasure
|> Some
let arg_16 =
(match node.["single"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("single")
)
)
| v -> v)
.AsValue()
.GetValue<System.Single> ()
|> LanguagePrimitives.Float32WithMeasure
let arg_15 =
(match node.["f32"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("f32")
)
)
| v -> v)
.AsValue()
.GetValue<System.Single> ()
|> LanguagePrimitives.Float32WithMeasure
let arg_14 =
(match node.["f"] with (match node.["f"] with
| null -> | null ->
raise ( raise (
@@ -303,9 +499,126 @@ module JsonRecordTypeWithBothJsonParseExtension =
sprintf "Required key '%s' not found on JSON object" ("f") sprintf "Required key '%s' not found on JSON object" ("f")
) )
) )
| v -> v)
.AsValue()
.GetValue<System.Double> ()
|> LanguagePrimitives.FloatWithMeasure
let arg_13 =
(match node.["u64"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("u64")
)
)
| v -> v)
.AsValue()
.GetValue<System.UInt64> ()
|> LanguagePrimitives.UInt64WithMeasure
let arg_12 =
(match node.["u32"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("u32")
)
)
| v -> v)
.AsValue()
.GetValue<System.UInt32> ()
|> LanguagePrimitives.UInt32WithMeasure
let arg_11 =
(match node.["u"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("u")
)
)
| v -> v)
.AsValue()
.GetValue<System.UInt32> ()
|> LanguagePrimitives.UInt32WithMeasure
let arg_10 =
(match node.["i64"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("i64")
)
)
| v -> v)
.AsValue()
.GetValue<System.Int64> ()
|> LanguagePrimitives.Int64WithMeasure
let arg_9 =
(match node.["i32"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("i32")
)
)
| v -> v)
.AsValue()
.GetValue<System.Int32> ()
|> LanguagePrimitives.Int32WithMeasure
let arg_8 =
(match node.["i"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("i")
)
)
| v -> v)
.AsValue()
.GetValue<System.Int32> ()
|> LanguagePrimitives.Int32WithMeasure
let arg_7 =
(match node.["sbyte"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("sbyte")
)
)
| v -> v)
.AsValue()
.GetValue<System.SByte> ()
|> LanguagePrimitives.SByteWithMeasure
let arg_6 =
(match node.["byte"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("byte")
)
)
| v -> v)
.AsValue()
.GetValue<System.Byte> ()
|> LanguagePrimitives.ByteWithMeasure
let arg_5 =
(match node.["arr"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("arr")
)
)
| v -> v) | v -> v)
.AsArray () .AsArray ()
|> Seq.map (fun elt -> elt.AsValue().GetValue<int> ()) |> Seq.map (fun elt -> elt.AsValue().GetValue<System.Int32> ())
|> Array.ofSeq |> Array.ofSeq
let arg_4 = let arg_4 =
@@ -318,7 +631,7 @@ module JsonRecordTypeWithBothJsonParseExtension =
) )
| v -> v) | v -> v)
.AsArray () .AsArray ()
|> Seq.map (fun elt -> elt.AsValue().GetValue<string> ()) |> Seq.map (fun elt -> elt.AsValue().GetValue<System.String> ())
|> Array.ofSeq |> Array.ofSeq
let arg_3 = let arg_3 =
@@ -343,7 +656,7 @@ module JsonRecordTypeWithBothJsonParseExtension =
) )
| v -> v) | v -> v)
.AsArray () .AsArray ()
|> Seq.map (fun elt -> elt.AsValue().GetValue<int> ()) |> Seq.map (fun elt -> elt.AsValue().GetValue<System.Int32> ())
|> List.ofSeq |> List.ofSeq
let arg_1 = let arg_1 =
@@ -356,7 +669,7 @@ module JsonRecordTypeWithBothJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_0 = let arg_0 =
(match node.["a"] with (match node.["a"] with
@@ -368,7 +681,7 @@ module JsonRecordTypeWithBothJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
{ {
A = arg_0 A = arg_0
@@ -376,7 +689,22 @@ module JsonRecordTypeWithBothJsonParseExtension =
C = arg_2 C = arg_2
D = arg_3 D = arg_3
E = arg_4 E = arg_4
F = arg_5 Arr = arg_5
Byte = arg_6
Sbyte = arg_7
I = arg_8
I32 = arg_9
I64 = arg_10
U = arg_11
U32 = arg_12
U64 = arg_13
F = arg_14
F32 = arg_15
Single = arg_16
IntMeasureOption = arg_17
IntMeasureNullable = arg_18
Enum = arg_19
Timestamp = arg_20
} }
namespace ConsumePlugin namespace ConsumePlugin
@@ -422,7 +750,7 @@ module FirstDuJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
) )
| "case2" -> | "case2" ->
let node = let node =
@@ -455,6 +783,62 @@ module FirstDuJsonParseExtension =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
) )
| v -> failwith ("Unrecognised 'type' field value: " + v) | v -> failwith ("Unrecognised 'type' field value: " + v)
namespace ConsumePlugin
/// Module containing JSON parsing extension members for the HeaderAndValue type
[<AutoOpen>]
module HeaderAndValueJsonParseExtension =
/// Extension methods for JSON parsing
type HeaderAndValue with
/// Parse from a JSON node.
static member jsonParse (node : System.Text.Json.Nodes.JsonNode) : HeaderAndValue =
let arg_1 =
(match node.["value"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("value")
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
let arg_0 =
(match node.["header"] with
| null ->
raise (
System.Collections.Generic.KeyNotFoundException (
sprintf "Required key '%s' not found on JSON object" ("header")
)
)
| v -> v)
.AsValue()
.GetValue<System.String> ()
{
Header = arg_0
Value = arg_1
}
namespace ConsumePlugin
/// Module containing JSON parsing extension members for the Foo type
[<AutoOpen>]
module FooJsonParseExtension =
/// Extension methods for JSON parsing
type Foo with
/// Parse from a JSON node.
static member jsonParse (node : System.Text.Json.Nodes.JsonNode) : Foo =
let arg_0 =
match node.["message"] with
| null -> None
| v -> HeaderAndValue.jsonParse v |> Some
{
Message = arg_0
}

View File

@@ -22,7 +22,7 @@ module JwtVaultAuthResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_9 = let arg_9 =
(match node.["orphan"] with (match node.["orphan"] with
@@ -34,7 +34,7 @@ module JwtVaultAuthResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<bool> () .GetValue<System.Boolean> ()
let arg_8 = let arg_8 =
(match node.["entity_id"] with (match node.["entity_id"] with
@@ -46,7 +46,7 @@ module JwtVaultAuthResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_7 = let arg_7 =
(match node.["token_type"] with (match node.["token_type"] with
@@ -58,7 +58,7 @@ module JwtVaultAuthResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_6 = let arg_6 =
(match node.["renewable"] with (match node.["renewable"] with
@@ -70,7 +70,7 @@ module JwtVaultAuthResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<bool> () .GetValue<System.Boolean> ()
let arg_5 = let arg_5 =
(match node.["lease_duration"] with (match node.["lease_duration"] with
@@ -82,7 +82,7 @@ module JwtVaultAuthResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_4 = let arg_4 =
(match node.["identity_policies"] with (match node.["identity_policies"] with
@@ -94,7 +94,7 @@ module JwtVaultAuthResponse =
) )
| v -> v) | v -> v)
.AsArray () .AsArray ()
|> Seq.map (fun elt -> elt.AsValue().GetValue<string> ()) |> Seq.map (fun elt -> elt.AsValue().GetValue<System.String> ())
|> List.ofSeq |> List.ofSeq
let arg_3 = let arg_3 =
@@ -107,7 +107,7 @@ module JwtVaultAuthResponse =
) )
| v -> v) | v -> v)
.AsArray () .AsArray ()
|> Seq.map (fun elt -> elt.AsValue().GetValue<string> ()) |> Seq.map (fun elt -> elt.AsValue().GetValue<System.String> ())
|> List.ofSeq |> List.ofSeq
let arg_2 = let arg_2 =
@@ -120,7 +120,7 @@ module JwtVaultAuthResponse =
) )
| v -> v) | v -> v)
.AsArray () .AsArray ()
|> Seq.map (fun elt -> elt.AsValue().GetValue<string> ()) |> Seq.map (fun elt -> elt.AsValue().GetValue<System.String> ())
|> List.ofSeq |> List.ofSeq
let arg_1 = let arg_1 =
@@ -133,7 +133,7 @@ module JwtVaultAuthResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_0 = let arg_0 =
(match node.["client_token"] with (match node.["client_token"] with
@@ -145,7 +145,7 @@ module JwtVaultAuthResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
{ {
ClientToken = arg_0 ClientToken = arg_0
@@ -189,7 +189,7 @@ module JwtVaultResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_2 = let arg_2 =
(match node.["renewable"] with (match node.["renewable"] with
@@ -201,7 +201,7 @@ module JwtVaultResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<bool> () .GetValue<System.Boolean> ()
let arg_1 = let arg_1 =
(match node.["lease_id"] with (match node.["lease_id"] with
@@ -213,7 +213,7 @@ module JwtVaultResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_0 = let arg_0 =
(match node.["request_id"] with (match node.["request_id"] with
@@ -225,7 +225,7 @@ module JwtVaultResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
{ {
RequestId = arg_0 RequestId = arg_0
@@ -271,7 +271,7 @@ module JwtSecretResponse =
.AsObject () .AsObject ()
|> Seq.map (fun kvp -> |> Seq.map (fun kvp ->
let key = (kvp.Key) let key = (kvp.Key)
let value = (kvp.Value).AsValue().GetValue<int> () let value = (kvp.Value).AsValue().GetValue<System.Int32> ()
key, value key, value
) )
|> Map.ofSeq |> Map.ofSeq
@@ -288,7 +288,7 @@ module JwtSecretResponse =
.AsObject () .AsObject ()
|> Seq.map (fun kvp -> |> Seq.map (fun kvp ->
let key = (kvp.Key) |> System.Uri let key = (kvp.Key) |> System.Uri
let value = (kvp.Value).AsValue().GetValue<string> () let value = (kvp.Value).AsValue().GetValue<System.String> ()
key, value key, value
) )
|> dict |> dict
@@ -305,7 +305,7 @@ module JwtSecretResponse =
.AsObject () .AsObject ()
|> Seq.map (fun kvp -> |> Seq.map (fun kvp ->
let key = (kvp.Key) |> System.Uri let key = (kvp.Key) |> System.Uri
let value = (kvp.Value).AsValue().GetValue<string> () let value = (kvp.Value).AsValue().GetValue<System.String> ()
key, value key, value
) )
|> readOnlyDict |> readOnlyDict
@@ -322,7 +322,7 @@ module JwtSecretResponse =
.AsObject () .AsObject ()
|> Seq.map (fun kvp -> |> Seq.map (fun kvp ->
let key = (kvp.Key) let key = (kvp.Key)
let value = (kvp.Value).AsValue().GetValue<string> () let value = (kvp.Value).AsValue().GetValue<System.String> ()
key, value key, value
) )
|> Map.ofSeq |> Map.ofSeq
@@ -339,7 +339,7 @@ module JwtSecretResponse =
.AsObject () .AsObject ()
|> Seq.map (fun kvp -> |> Seq.map (fun kvp ->
let key = (kvp.Key) let key = (kvp.Key)
let value = (kvp.Value).AsValue().GetValue<string> () let value = (kvp.Value).AsValue().GetValue<System.String> ()
key, value key, value
) )
|> Seq.map System.Collections.Generic.KeyValuePair |> Seq.map System.Collections.Generic.KeyValuePair
@@ -357,7 +357,7 @@ module JwtSecretResponse =
.AsObject () .AsObject ()
|> Seq.map (fun kvp -> |> Seq.map (fun kvp ->
let key = (kvp.Key) let key = (kvp.Key)
let value = (kvp.Value).AsValue().GetValue<string> () let value = (kvp.Value).AsValue().GetValue<System.String> ()
key, value key, value
) )
|> dict |> dict
@@ -374,7 +374,7 @@ module JwtSecretResponse =
.AsObject () .AsObject ()
|> Seq.map (fun kvp -> |> Seq.map (fun kvp ->
let key = (kvp.Key) let key = (kvp.Key)
let value = (kvp.Value).AsValue().GetValue<string> () let value = (kvp.Value).AsValue().GetValue<System.String> ()
key, value key, value
) )
|> readOnlyDict |> readOnlyDict
@@ -389,7 +389,7 @@ module JwtSecretResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<int> () .GetValue<System.Int32> ()
let arg_2 = let arg_2 =
(match node.["renewable"] with (match node.["renewable"] with
@@ -401,7 +401,7 @@ module JwtSecretResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<bool> () .GetValue<System.Boolean> ()
let arg_1 = let arg_1 =
(match node.["lease_id"] with (match node.["lease_id"] with
@@ -413,7 +413,7 @@ module JwtSecretResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
let arg_0 = let arg_0 =
(match node.["request_id"] with (match node.["request_id"] with
@@ -425,7 +425,7 @@ module JwtSecretResponse =
) )
| v -> v) | v -> v)
.AsValue() .AsValue()
.GetValue<string> () .GetValue<System.String> ()
{ {
RequestId = arg_0 RequestId = arg_0

View File

@@ -19,13 +19,16 @@ type GymAccessOptions =
QrCodeAccess : bool QrCodeAccess : bool
} }
[<Measure>]
type measure
[<WoofWare.Myriad.Plugins.JsonParse>] [<WoofWare.Myriad.Plugins.JsonParse>]
type GymLocation = type GymLocation =
{ {
[<JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)>] [<JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)>]
Longitude : float Longitude : float
[<JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)>] [<JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)>]
Latitude : float Latitude : float<measure>
} }
[<WoofWare.Myriad.Plugins.JsonParse>] [<WoofWare.Myriad.Plugins.JsonParse>]

View File

@@ -1,9 +1,5 @@
namespace ConsumePlugin namespace ConsumePlugin
type ParseState =
| AwaitingKey
| AwaitingValue of string
/// My whatnot /// My whatnot
[<WoofWare.Myriad.Plugins.RemoveOptions>] [<WoofWare.Myriad.Plugins.RemoveOptions>]
type RecordType = type RecordType =

View File

@@ -16,6 +16,15 @@ type InnerTypeWithBoth =
ConcreteDict : Dictionary<string, InnerTypeWithBoth> ConcreteDict : Dictionary<string, InnerTypeWithBoth>
} }
[<WoofWare.Myriad.Plugins.JsonParse true>]
[<WoofWare.Myriad.Plugins.JsonSerialize true>]
type SomeEnum =
| Blah = 1
| Thing = 0
[<Measure>]
type measure
[<WoofWare.Myriad.Plugins.JsonParse true>] [<WoofWare.Myriad.Plugins.JsonParse true>]
[<WoofWare.Myriad.Plugins.JsonSerialize true>] [<WoofWare.Myriad.Plugins.JsonSerialize true>]
type JsonRecordTypeWithBoth = type JsonRecordTypeWithBoth =
@@ -25,7 +34,22 @@ type JsonRecordTypeWithBoth =
C : int list C : int list
D : InnerTypeWithBoth D : InnerTypeWithBoth
E : string array E : string array
F : int[] Arr : int[]
Byte : byte<measure>
Sbyte : sbyte<measure>
I : int<measure>
I32 : int32<measure>
I64 : int64<measure>
U : uint<measure>
U32 : uint32<measure>
U64 : uint64<measure>
F : float<measure>
F32 : float32<measure>
Single : single<measure>
IntMeasureOption : int<measure> option
IntMeasureNullable : int<measure> Nullable
Enum : SomeEnum
Timestamp : DateTimeOffset
} }
[<WoofWare.Myriad.Plugins.JsonSerialize true>] [<WoofWare.Myriad.Plugins.JsonSerialize true>]
@@ -34,3 +58,18 @@ type FirstDu =
| EmptyCase | EmptyCase
| Case1 of data : string | Case1 of data : string
| Case2 of record : JsonRecordTypeWithBoth * i : int | Case2 of record : JsonRecordTypeWithBoth * i : int
[<WoofWare.Myriad.Plugins.JsonParse true>]
[<WoofWare.Myriad.Plugins.JsonSerialize true>]
type HeaderAndValue =
{
Header : string
Value : string
}
[<WoofWare.Myriad.Plugins.JsonSerialize true>]
[<WoofWare.Myriad.Plugins.JsonParse true>]
type Foo =
{
Message : HeaderAndValue option
}

View File

@@ -10,7 +10,7 @@
<WarnOn>FS3388,FS3559</WarnOn> <WarnOn>FS3388,FS3559</WarnOn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Nerdbank.GitVersioning" Version="3.6.139" PrivateAssets="all"/> <PackageReference Include="Nerdbank.GitVersioning" Version="3.6.141" PrivateAssets="all"/>
<SourceLinkGitHubHost Include="github.com" ContentUrl="https://raw.githubusercontent.com"/> <SourceLinkGitHubHost Include="github.com" ContentUrl="https://raw.githubusercontent.com"/>
</ItemGroup> </ItemGroup>
<PropertyGroup Condition="'$(GITHUB_ACTION)' != ''"> <PropertyGroup Condition="'$(GITHUB_ACTION)' != ''">

View File

@@ -8,23 +8,20 @@
Some helpers in [Myriad](https://github.com/MoiraeSoftware/myriad/) which might be useful. 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. Currently implemented:
The `RemoveOptions` generator in particular is extremely half-baked.
* `JsonParse` (to stamp out `jsonParse : JsonNode -> 'T` methods).
* `JsonSerialize` (to stamp out `toJsonNode : 'T -> JsonNode` methods).
* `HttpClient` (to stamp out a [RestEase](https://github.com/canton7/RestEase)-style HTTP client).
* `GenerateMock` (to stamp out a record type corresponding to an interface, like a compile-time [Foq](https://github.com/fsprojects/Foq)).
* `CreateCatamorphism` (to stamp out a non-stack-overflowing [catamorphism](https://fsharpforfunandprofit.com/posts/recursive-types-and-folds/) for a discriminated union).
* `RemoveOptions` (to strip `option` modifiers from a type) - this one is particularly half-baked!
If you would like to ensure that your particular use-case remains unbroken, please do contribute tests to this repository. If you would like to ensure that your particular use-case remains unbroken, please do contribute tests to this repository.
The `ConsumePlugin` assembly contains a number of invocations of these source generators, The `ConsumePlugin` assembly contains a number of invocations of these source generators,
so you just need to add copies of your types to that assembly to ensure that I will at least notice if I break the build; so you just need to add copies of your types to that assembly to ensure that I will at least notice if I break the build;
and if you add tests to `WoofWare.Myriad.Plugins.Test` then I will also notice if I break the runtime semantics of the generated code. and if you add tests to `WoofWare.Myriad.Plugins.Test` then I will also notice if I break the runtime semantics of the generated code.
Currently implemented:
* `JsonParse` (to stamp out `jsonParse : JsonNode -> 'T` methods);
* `JsonSerialize` (to stamp out `toJsonNode : 'T -> JsonNode` methods);
* `RemoveOptions` (to strip `option` modifiers from a type).
* `HttpClient` (to stamp out a [RestEase](https://github.com/canton7/RestEase)-style HTTP client).
* `GenerateMock` (to stamp out a record type corresponding to an interface).
* `CreateCatamorphism` (to stamp out a non-stack-overflowing [catamorphism](https://fsharpforfunandprofit.com/posts/recursive-types-and-folds/) for a discriminated union).
## `JsonParse` ## `JsonParse`
Takes records like this: Takes records like this:

View File

@@ -12,10 +12,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ApiSurface" Version="4.0.41" /> <PackageReference Include="ApiSurface" Version="4.0.44" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/>
<PackageReference Include="NUnit" Version="4.1.0"/> <PackageReference Include="NUnit" Version="4.1.0"/>
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/> <PackageReference Include="NUnit3TestAdapter" Version="4.6.0"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -10,6 +10,6 @@
":/Directory.Build.props", ":/Directory.Build.props",
":/global.json", ":/global.json",
"./", "./",
"^./Test" ":^Test"
] ]
} }

View File

@@ -58,7 +58,7 @@ module PureGymDtos =
[ [
"""{"latitude": 1.0, "longitude": 3.0}""", """{"latitude": 1.0, "longitude": 3.0}""",
{ {
GymLocation.Latitude = 1.0 GymLocation.Latitude = 1.0<measure>
Longitude = 3.0 Longitude = 3.0
} }
] ]
@@ -96,7 +96,7 @@ module PureGymDtos =
Location = Location =
{ {
Longitude = -0.110252 Longitude = -0.110252
Latitude = 51.480401 Latitude = 51.480401<measure>
} }
TimeZone = "Europe/London" TimeZone = "Europe/London"
ReopenDate = "2021-04-12T00:00:00+01 Europe/London" ReopenDate = "2021-04-12T00:00:00+01 Europe/London"

View File

@@ -43,7 +43,7 @@ module TestGift =
member _.WithACard g message = member _.WithACard g message =
$"%s{g} with a card saying '%s{message}'" $"%s{g} with a card saying '%s{message}'"
member _.Wrapped g paper = $"%s{g} wrapped in %A{paper} paper" member _.Wrapped g paper = $"%s{g} wrapped in %O{paper} paper"
} }
} }

View File

@@ -49,3 +49,15 @@ module TestJsonParse =
let actual = s |> JsonNode.Parse |> InnerType.jsonParse let actual = s |> JsonNode.Parse |> InnerType.jsonParse
actual |> shouldEqual expected actual |> shouldEqual expected
[<TestCase("thing", SomeEnum.Thing)>]
[<TestCase("Thing", SomeEnum.Thing)>]
[<TestCase("THING", SomeEnum.Thing)>]
[<TestCase("blah", SomeEnum.Blah)>]
[<TestCase("Blah", SomeEnum.Blah)>]
[<TestCase("BLAH", SomeEnum.Blah)>]
let ``Can deserialise enum`` (str : string, expected : SomeEnum) =
sprintf "\"%s\"" str
|> JsonNode.Parse
|> SomeEnum.jsonParse
|> shouldEqual expected

View File

@@ -77,7 +77,22 @@ module TestJsonSerde =
let! depth = Gen.choose (0, 2) let! depth = Gen.choose (0, 2)
let! d = innerGen depth let! d = innerGen depth
let! e = Gen.arrayOf Arb.generate<NonNull<string>> let! e = Gen.arrayOf Arb.generate<NonNull<string>>
let! f = Gen.arrayOf Arb.generate<int> let! arr = Gen.arrayOf Arb.generate<int>
let! byte = Arb.generate
let! sbyte = Arb.generate
let! i = Arb.generate
let! i32 = Arb.generate
let! i64 = Arb.generate
let! u = Arb.generate
let! u32 = Arb.generate
let! u64 = Arb.generate
let! f = Arb.generate |> Gen.filter (fun s -> Double.IsFinite (s / 1.0<measure>))
let! f32 = Arb.generate |> Gen.filter (fun s -> Single.IsFinite (s / 1.0f<measure>))
let! single = Arb.generate |> Gen.filter (fun s -> Single.IsFinite (s / 1.0f<measure>))
let! intMeasureOption = Arb.generate
let! intMeasureNullable = Arb.generate
let! someEnum = Gen.choose (0, 1)
let! timestamp = Arb.generate
return return
{ {
@@ -86,7 +101,22 @@ module TestJsonSerde =
C = c C = c
D = d D = d
E = e |> Array.map _.Get E = e |> Array.map _.Get
Arr = arr
Byte = byte
Sbyte = sbyte
I = i
I32 = i32
I64 = i64
U = u
U32 = u32
U64 = u64
F = f F = f
F32 = f32
Single = single
IntMeasureOption = intMeasureOption
IntMeasureNullable = intMeasureNullable
Enum = enum<SomeEnum> someEnum
Timestamp = timestamp
} }
} }
@@ -104,6 +134,80 @@ module TestJsonSerde =
property |> Prop.forAll (Arb.fromGen outerGen) |> Check.QuickThrowOnFailure property |> Prop.forAll (Arb.fromGen outerGen) |> Check.QuickThrowOnFailure
[<Test>]
let ``Single example of big record`` () =
let guid = Guid.Parse "dfe24db5-9f8d-447b-8463-4c0bcf1166d5"
let data =
{
A = 3
B = "hello!"
C = [ 1 ; -9 ]
D =
{
Thing = guid
Map = Map.ofList []
ReadOnlyDict = readOnlyDict []
Dict = dict []
ConcreteDict = Dictionary ()
}
E = [| "I'm-a-string" |]
Arr = [| -18883 ; 9100 |]
Byte = 87uy<measure>
Sbyte = 89y<measure>
I = 199993345<measure>
I32 = -485832<measure>
I64 = -13458625689L<measure>
U = 458582u<measure>
U32 = 857362147u<measure>
U64 = 1234567892123414596UL<measure>
F = 8833345667.1<measure>
F32 = 1000.98f<measure>
Single = 0.334f<measure>
IntMeasureOption = Some 981<measure>
IntMeasureNullable = Nullable -883<measure>
Enum = enum<SomeEnum> 1
Timestamp = DateTimeOffset (2024, 07, 01, 17, 54, 00, TimeSpan.FromHours 1.0)
}
let expected =
"""{
"a": 3,
"b": "hello!",
"c": [1, -9],
"d": {
"it\u0027s-a-me": "dfe24db5-9f8d-447b-8463-4c0bcf1166d5",
"map": {},
"readOnlyDict": {},
"dict": {},
"concreteDict": {}
},
"e": ["I\u0027m-a-string"],
"arr": [-18883, 9100],
"byte": 87,
"sbyte": 89,
"i": 199993345,
"i32": -485832,
"i64": -13458625689,
"u": 458582,
"u32": 857362147,
"u64": 1234567892123414596,
"f": 8833345667.1,
"f32": 1000.98,
"single": 0.334,
"intMeasureOption": 981,
"intMeasureNullable": -883,
"enum": 1,
"timestamp": "2024-07-01T17:54:00.0000000\u002B01:00"
}
"""
|> fun s -> s.ToCharArray ()
|> Array.filter (fun c -> not (Char.IsWhiteSpace c))
|> fun s -> new String (s)
JsonRecordTypeWithBoth.toJsonNode(data).ToJsonString () |> shouldEqual expected
JsonRecordTypeWithBoth.jsonParse (JsonNode.Parse expected) |> shouldEqual data
[<Test>] [<Test>]
let ``Guids are treated just like strings`` () = let ``Guids are treated just like strings`` () =
let guidStr = "b1e7496e-6e79-4158-8579-a01de355d3b2" let guidStr = "b1e7496e-6e79-4158-8579-a01de355d3b2"
@@ -140,8 +244,7 @@ module TestJsonSerde =
} }
let sanitiseRec (r : JsonRecordTypeWithBoth) : JsonRecordTypeWithBoth = let sanitiseRec (r : JsonRecordTypeWithBoth) : JsonRecordTypeWithBoth =
{ { r with
A = r.A
B = if isNull r.B then "<null>" else r.B B = if isNull r.B then "<null>" else r.B
C = C =
if Object.ReferenceEquals (r.C, (null : obj)) then if Object.ReferenceEquals (r.C, (null : obj)) then
@@ -150,11 +253,11 @@ module TestJsonSerde =
r.C r.C
D = sanitiseInner r.D D = sanitiseInner r.D
E = if isNull r.E then [||] else r.E E = if isNull r.E then [||] else r.E
F = Arr =
if Object.ReferenceEquals (r.F, (null : obj)) then if Object.ReferenceEquals (r.Arr, (null : obj)) then
[||] [||]
else else
r.F r.Arr
} }
let duGen = let duGen =

View File

@@ -33,12 +33,12 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ApiSurface" Version="4.0.41"/> <PackageReference Include="ApiSurface" Version="4.0.44"/>
<PackageReference Include="FsCheck" Version="2.16.6"/> <PackageReference Include="FsCheck" Version="2.16.6"/>
<PackageReference Include="FsUnit" Version="6.0.0"/> <PackageReference Include="FsUnit" Version="6.0.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/>
<PackageReference Include="NUnit" Version="4.1.0"/> <PackageReference Include="NUnit" Version="4.1.0"/>
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/> <PackageReference Include="NUnit3TestAdapter" Version="4.6.0"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -62,13 +62,46 @@ type internal InterfaceType =
type internal RecordType = type internal RecordType =
{ {
Name : Ident Name : Ident
Fields : SynField seq Fields : SynField list
/// Any additional members which are not record fields.
Members : SynMemberDefns option Members : SynMemberDefns option
XmlDoc : PreXmlDoc option XmlDoc : PreXmlDoc option
Generics : SynTyparDecls option Generics : SynTyparDecls option
Accessibility : SynAccess option Accessibility : SynAccess option
Attributes : SynAttribute list
} }
/// Parse from the AST.
static member OfRecord (record : SynTypeDefn) : RecordType =
let sci, sdr, smd, smdo =
match record with
| SynTypeDefn.SynTypeDefn (sci, sdr, smd, smdo, _, _) -> sci, sdr, smd, smdo
let synAccessOption, recordFields =
match sdr with
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Record (sa, fields, _), _) -> sa, fields
| _ -> failwith $"expected a record; got: %+A{record}"
match sci with
| SynComponentInfo.SynComponentInfo (attrs, typars, _, longId, doc, _, access, _) ->
if access <> synAccessOption then
failwith
$"TODO what's happened, two different accessibility modifiers: %O{access} and %O{synAccessOption}"
match smdo with
| Some v -> failwith $"TODO what's happened, got a synMemberDefn of %O{v}"
| None -> ()
{
Name = List.last longId
Fields = recordFields
Members = if smd.IsEmpty then None else Some smd
XmlDoc = if doc.IsEmpty then None else Some doc
Generics = typars
Accessibility = synAccessOption
Attributes = attrs |> List.collect (fun l -> l.Attributes)
}
/// Anything that is part of an ADT. /// Anything that is part of an ADT.
/// A record is a product of stuff; this type represents one of those stuffs. /// A record is a product of stuff; this type represents one of those stuffs.
type internal AdtNode = type internal AdtNode =
@@ -96,10 +129,15 @@ type internal AdtProduct =
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
module internal AstHelper = module internal AstHelper =
let instantiateRecord (fields : (RecordFieldName * SynExpr option) list) : SynExpr = let isEnum (SynTypeDefn.SynTypeDefn (_, repr, _, _, _, _)) : bool =
match repr with
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Enum _, _) -> true
| _ -> false
let instantiateRecord (fields : (SynLongIdent * SynExpr) list) : SynExpr =
let fields = let fields =
fields fields
|> List.map (fun (rfn, synExpr) -> SynExprRecordField (rfn, Some range0, synExpr, None)) |> List.map (fun (rfn, synExpr) -> SynExprRecordField ((rfn, true), Some range0, Some synExpr, None))
SynExpr.Record (None, None, fields, range0) SynExpr.Record (None, None, fields, range0)

View File

@@ -1070,17 +1070,11 @@ module internal CataGenerator =
body body
|> SynExpr.createLet |> SynExpr.createLet
[ [
SynExpr.TypeApp ( (SynExpr.createIdent "ResizeArray")
SynExpr.createIdent "ResizeArray", |> SynExpr.typeApp
range0,
[ [
SynType.var (SynTypar.SynTypar (unionCase.GenericName, TyparStaticReq.None, false)) SynType.var (SynTypar.SynTypar (unionCase.GenericName, TyparStaticReq.None, false))
], ]
[],
Some range0,
range0,
range0
)
|> SynExpr.applyTo (SynExpr.CreateConst ()) |> SynExpr.applyTo (SynExpr.CreateConst ())
|> SynBinding.basic [ unionCase.StackName ] [] |> SynBinding.basic [ unionCase.StackName ] []
] ]
@@ -1106,7 +1100,7 @@ module internal CataGenerator =
let moduleName = parentName + "Cata" |> Ident.create let moduleName = parentName + "Cata" |> Ident.create
let modInfo = let modInfo =
SynComponentInfo.create (parentName + "Cata" |> Ident.create) SynComponentInfo.create moduleName
|> SynComponentInfo.withDocString ( |> SynComponentInfo.withDocString (
PreXmlDoc.Create $" Methods to perform a catamorphism over the type %s{parentName}" PreXmlDoc.Create $" Methods to perform a catamorphism over the type %s{parentName}"
) )

View File

@@ -257,11 +257,7 @@ module internal HttpClientGenerator =
| Some id -> id | Some id -> id
let urlSeparator = let urlSeparator =
// apparent Myriad bug: `IndexOf '?'` gets formatted as `IndexOf ?` which is clearly wrong let questionMark = SynExpr.CreateConst '?'
let questionMark =
SynExpr.CreateConst 63
|> SynExpr.applyFunction (SynExpr.createIdent "char")
|> SynExpr.paren
let containsQuestion = let containsQuestion =
info.UrlTemplate info.UrlTemplate
@@ -425,21 +421,17 @@ module internal HttpClientGenerator =
(SynExpr.createIdent' bodyParamName) (SynExpr.createIdent' bodyParamName)
) )
Do ( Do (
SynExpr.LongIdentSet ( SynExpr.assign
SynLongIdent.createS' [ "httpMessage" ; "Content" ], (SynLongIdent.createS' [ "httpMessage" ; "Content" ])
SynExpr.createIdent "queryParams", (SynExpr.createIdent "queryParams")
range0
)
) )
] ]
| BodyParamMethods.HttpContent -> | BodyParamMethods.HttpContent ->
[ [
Do ( Do (
SynExpr.LongIdentSet ( SynExpr.assign
SynLongIdent.createS' [ "httpMessage" ; "Content" ], (SynLongIdent.createS' [ "httpMessage" ; "Content" ])
SynExpr.createIdent' bodyParamName, (SynExpr.createIdent' bodyParamName)
range0
)
) )
] ]
| BodyParamMethods.Serialise ty -> | BodyParamMethods.Serialise ty ->
@@ -449,7 +441,7 @@ module internal HttpClientGenerator =
SynExpr.createNew SynExpr.createNew
(SynType.createLongIdent' [ "System" ; "Net" ; "Http" ; "StringContent" ]) (SynType.createLongIdent' [ "System" ; "Net" ; "Http" ; "StringContent" ])
(SynExpr.createIdent' bodyParamName (SynExpr.createIdent' bodyParamName
|> SynExpr.pipeThroughFunction (JsonSerializeGenerator.serializeNode ty) |> SynExpr.pipeThroughFunction (fst (JsonSerializeGenerator.serializeNode ty))
|> SynExpr.pipeThroughFunction ( |> SynExpr.pipeThroughFunction (
SynExpr.createLambda SynExpr.createLambda
"node" "node"
@@ -464,11 +456,9 @@ module internal HttpClientGenerator =
)) ))
) )
Do ( Do (
SynExpr.LongIdentSet ( SynExpr.assign
SynLongIdent.createS' [ "httpMessage" ; "Content" ], (SynLongIdent.createS' [ "httpMessage" ; "Content" ])
SynExpr.createIdent "queryParams", (SynExpr.createIdent "queryParams")
range0
)
) )
] ]
@@ -695,7 +685,7 @@ module internal HttpClientGenerator =
let headerInfo = let headerInfo =
match extractHeaderInformation pi.Attributes with match extractHeaderInformation pi.Attributes with
| [ [ x ] ] -> x | [ [ x ] ] -> x
| [ xs ] -> | [ _ ] ->
failwith failwith
"Expected exactly one Header parameter on the member, with exactly one arg; got one Header parameter with non-1-many args" "Expected exactly one Header parameter on the member, with exactly one arg; got one Header parameter with non-1-many args"
| [] -> | [] ->

View File

@@ -71,13 +71,13 @@ module internal InterfaceMockGenerator =
if inherits.Contains KnownInheritance.IDisposable then if inherits.Contains KnownInheritance.IDisposable then
let unitFun = SynExpr.createThunk (SynExpr.CreateConst ()) let unitFun = SynExpr.createThunk (SynExpr.CreateConst ())
[ (SynLongIdent.createS "Dispose", true), Some unitFun ] [ SynLongIdent.createS "Dispose", unitFun ]
else else
[] []
let nonExtras = let nonExtras =
fields fields
|> List.map (fun field -> (SynLongIdent.createI (getName field), true), Some (failwithFun field)) |> List.map (fun field -> SynLongIdent.createI (getName field), failwithFun field)
extras @ nonExtras extras @ nonExtras
@@ -213,6 +213,7 @@ module internal InterfaceMockGenerator =
XmlDoc = Some xmlDoc XmlDoc = Some xmlDoc
Generics = interfaceType.Generics Generics = interfaceType.Generics
Accessibility = Some access Accessibility = Some access
Attributes = []
} }
let typeDecl = AstHelper.defineRecordType record let typeDecl = AstHelper.defineRecordType record

View File

@@ -24,7 +24,7 @@ module internal JsonParseGenerator =
JsonNumberHandlingArg = None JsonNumberHandlingArg = None
} }
/// (match {indexed} with | null -> raise (System.Collections.Generic.KeyNotFoundException ()) | v -> v) /// (match {indexed} with | null -> raise (System.Collections.Generic.KeyNotFoundException ({propertyName} not found)) | v -> v)
let assertNotNull (propertyName : SynExpr) (indexed : SynExpr) = let assertNotNull (propertyName : SynExpr) (indexed : SynExpr) =
let raiseExpr = let raiseExpr =
SynExpr.applyFunction SynExpr.applyFunction
@@ -95,25 +95,8 @@ module internal JsonParseGenerator =
) )
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ collectionType ; "ofSeq" ]) |> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ collectionType ; "ofSeq" ])
/// match {node} with | null -> None | v -> {body} |> Some let dotParse (typeName : LongIdent) : LongIdent =
/// Use the variable `v` to get access to the `Some`. List.append typeName [ Ident.create "Parse" ]
let createParseLineOption (node : SynExpr) (body : SynExpr) : SynExpr =
let body = SynExpr.pipeThroughFunction (SynExpr.createIdent "Some") body
[
SynMatchClause.create SynPat.createNull (SynExpr.createIdent "None")
SynMatchClause.create (SynPat.named "v") body
]
|> SynExpr.createMatch node
/// Given e.g. "float", returns "System.Double.Parse"
let parseFunction (typeName : string) : LongIdent =
let qualified =
match Primitives.qualifyType typeName with
| Some x -> x
| None -> failwith $"Could not recognise type %s{typeName} as a primitive."
List.append qualified [ Ident.create "Parse" ]
/// fun kvp -> let key = {key(kvp)} in let value = {value(kvp)} in (key, value)) /// fun kvp -> let key = {key(kvp)} in let value = {value(kvp)} in (key, value))
/// The inputs will be fed with appropriate SynExprs to apply them to the `kvp.Key` and `kvp.Value` args. /// The inputs will be fed with appropriate SynExprs to apply them to the `kvp.Key` and `kvp.Value` args.
@@ -140,6 +123,47 @@ module internal JsonParseGenerator =
failwithf failwithf
$"Unable to parse the key type %+A{desiredType} of a JSON object. Keys are strings, and this plugin does not know how to convert to that from a string." $"Unable to parse the key type %+A{desiredType} of a JSON object. Keys are strings, and this plugin does not know how to convert to that from a string."
let private parseNumberType
(options : JsonParseOption)
(propertyName : SynExpr option)
(node : SynExpr)
(typeName : LongIdent)
=
let basic = asValueGetValueIdent propertyName typeName node
match options.JsonNumberHandlingArg with
| None -> basic
| Some option ->
let cond =
SynExpr.DotGet (SynExpr.createIdent "exc", range0, SynLongIdent.createS "Message", range0)
|> SynExpr.callMethodArg "Contains" (SynExpr.CreateConst "cannot be converted to")
let handler =
asValueGetValue propertyName "string" node
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent' (typeName |> dotParse))
|> SynExpr.ifThenElse
(SynExpr.equals
option
(SynExpr.createLongIdent
[
"System"
"Text"
"Json"
"Serialization"
"JsonNumberHandling"
"AllowReadingFromString"
]))
SynExpr.reraise
|> SynExpr.ifThenElse cond SynExpr.reraise
basic
|> SynExpr.pipeThroughTryWith
(SynPat.IsInst (
SynType.LongIdent (SynLongIdent.createS' [ "System" ; "InvalidOperationException" ]),
range0
))
handler
/// Given `node.["town"]`, for example, choose how to obtain a JSON value from it. /// Given `node.["town"]`, for example, choose how to obtain a JSON value from it.
/// The property name is used in error messages at runtime to show where a JSON /// The property name is used in error messages at runtime to show where a JSON
/// parse error occurred; supply `None` to indicate "don't validate". /// parse error occurred; supply `None` to indicate "don't validate".
@@ -168,45 +192,36 @@ module internal JsonParseGenerator =
node node
|> asValueGetValue propertyName "string" |> asValueGetValue propertyName "string"
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "DateTime" ; "Parse" ]) |> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "DateTime" ; "Parse" ])
| NumberType typeName -> | DateTimeOffset ->
let basic = asValueGetValue propertyName typeName node node
|> asValueGetValue propertyName "string"
match options.JsonNumberHandlingArg with |> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "DateTimeOffset" ; "Parse" ])
| None -> basic | NumberType typeName -> parseNumberType options propertyName node typeName
| Some option ->
let cond =
SynExpr.DotGet (SynExpr.createIdent "exc", range0, SynLongIdent.createS "Message", range0)
|> SynExpr.callMethodArg "Contains" (SynExpr.CreateConst "cannot be converted to")
let handler =
asValueGetValue propertyName "string" node
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent' (parseFunction typeName))
|> SynExpr.ifThenElse
(SynExpr.equals
option
(SynExpr.createLongIdent
[
"System"
"Text"
"Json"
"Serialization"
"JsonNumberHandling"
"AllowReadingFromString"
]))
SynExpr.reraise
|> SynExpr.ifThenElse cond SynExpr.reraise
basic
|> SynExpr.pipeThroughTryWith
(SynPat.IsInst (
SynType.LongIdent (SynLongIdent.createS' [ "System" ; "InvalidOperationException" ]),
range0
))
handler
| PrimitiveType typeName -> asValueGetValueIdent propertyName typeName node | PrimitiveType typeName -> asValueGetValueIdent propertyName typeName node
| OptionType ty -> | OptionType ty ->
parseNode None options ty (SynExpr.createIdent "v") let someClause =
|> createParseLineOption node parseNode None options ty (SynExpr.createIdent "v")
|> SynExpr.pipeThroughFunction (SynExpr.createIdent "Some")
|> SynMatchClause.create (SynPat.named "v")
[
SynMatchClause.create SynPat.createNull (SynExpr.createIdent "None")
someClause
]
|> SynExpr.createMatch node
| NullableType ty ->
let someClause =
parseNode None options ty (SynExpr.createIdent "v")
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "Nullable" ])
|> SynMatchClause.create (SynPat.named "v")
[
SynMatchClause.create
SynPat.createNull
(SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "Nullable" ]) (SynExpr.CreateConst ()))
someClause
]
|> SynExpr.createMatch node
| ListType ty -> | ListType ty ->
parseNode None options ty (SynExpr.createIdent "elt") parseNode None options ty (SynExpr.createIdent "elt")
|> asArrayMapped propertyName "List" node |> asArrayMapped propertyName "List" node
@@ -261,6 +276,9 @@ module internal JsonParseGenerator =
|> SynExpr.callMethod "ToJsonString" |> SynExpr.callMethod "ToJsonString"
|> SynExpr.paren |> SynExpr.paren
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "Numerics" ; "BigInteger" ; "Parse" ]) |> SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "Numerics" ; "BigInteger" ; "Parse" ])
| Measure (_measure, primType) ->
parseNumberType options propertyName node primType
|> SynExpr.pipeThroughFunction (Measure.getLanguagePrimitivesMeasure primType)
| _ -> | _ ->
// Let's just hope that we've also got our own type annotation! // Let's just hope that we've also got our own type annotation!
let typeName = let typeName =
@@ -389,9 +407,7 @@ module internal JsonParseGenerator =
let finalConstruction = let finalConstruction =
fields fields
|> List.mapi (fun i fieldData -> |> List.mapi (fun i fieldData -> SynLongIdent.createI fieldData.Ident, SynExpr.createIdent $"arg_%i{i}")
(SynLongIdent.createI fieldData.Ident, true), Some (SynExpr.createIdent $"arg_%i{i}")
)
|> AstHelper.instantiateRecord |> AstHelper.instantiateRecord
(finalConstruction, assignments) (finalConstruction, assignments)
@@ -474,6 +490,59 @@ module internal JsonParseGenerator =
|> SynBinding.basic [ Ident.create "ty" ] [] |> SynBinding.basic [ Ident.create "ty" ] []
] ]
let createEnumMaker
(spec : JsonParseOutputSpec)
(typeName : LongIdent)
(fields : (Ident * SynExpr) list)
: SynExpr
=
let numberKind =
[ "System" ; "Text" ; "Json" ; "JsonValueKind" ; "Number" ]
|> List.map Ident.create
let stringKind =
[ "System" ; "Text" ; "Json" ; "JsonValueKind" ; "String" ]
|> List.map Ident.create
let fail =
SynExpr.plus
(SynExpr.CreateConst "Unrecognised kind for enum of type: ")
(SynExpr.CreateConst (typeName |> List.map _.idText |> String.concat "."))
|> SynExpr.paren
|> SynExpr.applyFunction (SynExpr.createIdent "failwith")
let failString =
SynExpr.plus (SynExpr.CreateConst "Unrecognised value for enum: %i") (SynExpr.createIdent "v")
|> SynExpr.paren
|> SynExpr.applyFunction (SynExpr.createIdent "failwith")
let parseString =
fields
|> List.map (fun (ident, _) ->
SynMatchClause.create
(SynPat.createConst (
SynConst.String (ident.idText.ToLowerInvariant (), SynStringKind.Regular, range0)
))
(SynExpr.createLongIdent' (typeName @ [ ident ]))
)
|> fun l -> l @ [ SynMatchClause.create (SynPat.named "v") failString ]
|> SynExpr.createMatch (
asValueGetValue None "string" (SynExpr.createIdent "node")
|> SynExpr.callMethod "ToLowerInvariant"
)
[
SynMatchClause.create
(SynPat.identWithArgs numberKind (SynArgPats.create []))
(asValueGetValue None "int" (SynExpr.createIdent "node")
|> SynExpr.pipeThroughFunction (
SynExpr.typeApp [ SynType.createLongIdent typeName ] (SynExpr.createIdent "enum")
))
SynMatchClause.create (SynPat.identWithArgs stringKind (SynArgPats.create [])) parseString
SynMatchClause.create (SynPat.named "_") fail
]
|> SynExpr.createMatch (SynExpr.callMethod "GetValueKind" (SynExpr.createIdent "node"))
let createModule (namespaceId : LongIdent) (spec : JsonParseOutputSpec) (typeDefn : SynTypeDefn) = let createModule (namespaceId : LongIdent) (spec : JsonParseOutputSpec) (typeDefn : SynTypeDefn) =
let (SynTypeDefn (synComponentInfo, synTypeDefnRepr, _members, _implicitCtor, _, _)) = let (SynTypeDefn (synComponentInfo, synTypeDefnRepr, _members, _implicitCtor, _, _)) =
typeDefn typeDefn
@@ -534,6 +603,13 @@ module internal JsonParseGenerator =
|> List.map SynUnionCase.extract |> List.map SynUnionCase.extract
|> List.map (UnionCase.mapIdentFields optionGet) |> List.map (UnionCase.mapIdentFields optionGet)
|> createUnionMaker spec ident |> createUnionMaker spec ident
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Enum (cases, _range), _) ->
cases
|> List.map (fun c ->
match c with
| SynEnumCase.SynEnumCase (_, SynIdent.SynIdent (ident, _), value, _, _, _) -> ident, value
)
|> createEnumMaker spec ident
| _ -> failwithf "Not a record or union type" | _ -> failwithf "Not a record or union type"
[ scaffolding spec ident decl ] [ scaffolding spec ident decl ]
@@ -555,20 +631,21 @@ type JsonParseGenerator () =
let ast, _ = let ast, _ =
Ast.fromFilename context.InputFilename |> Async.RunSynchronously |> Array.head Ast.fromFilename context.InputFilename |> Async.RunSynchronously |> Array.head
let recordsAndUnions = let relevantTypes =
Ast.extractTypeDefn ast Ast.extractTypeDefn ast
|> List.map (fun (name, defns) -> |> List.map (fun (name, defns) ->
defns defns
|> List.choose (fun defn -> |> List.choose (fun defn ->
if Ast.isRecord defn then Some defn if Ast.isRecord defn then Some defn
elif Ast.isDu defn then Some defn elif Ast.isDu defn then Some defn
elif AstHelper.isEnum defn then Some defn
else None else None
) )
|> fun defns -> name, defns |> fun defns -> name, defns
) )
let namespaceAndTypes = let namespaceAndTypes =
recordsAndUnions relevantTypes
|> List.choose (fun (ns, types) -> |> List.choose (fun (ns, types) ->
types types
|> List.choose (fun typeDef -> |> List.choose (fun typeDef ->

View File

@@ -13,41 +13,65 @@ type internal JsonSerializeOutputSpec =
module internal JsonSerializeGenerator = module internal JsonSerializeGenerator =
open Fantomas.FCS.Text.Range open Fantomas.FCS.Text.Range
// The absolutely galaxy-brained implementation of JsonValue has `JsonValue.Parse "null"`
// identically equal to null. We have to work around this later, but we might as well just
// be efficient here and whip up the null directly.
let private jsonNull () =
SynExpr.createNull ()
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
/// Given `input.Ident`, for example, choose how to add it to the ambient `node`. /// Given `input.Ident`, for example, choose how to add it to the ambient `node`.
/// The result is a line like `(fun ident -> InnerType.toJsonNode ident)` or `(fun ident -> JsonValue.Create ident)`. /// The result is a line like `(fun ident -> InnerType.toJsonNode ident)` or `(fun ident -> JsonValue.Create ident)`.
let rec serializeNode (fieldType : SynType) : SynExpr = /// Returns also a bool which is true if the resulting SynExpr represents something of type JsonNode.
let rec serializeNode (fieldType : SynType) : SynExpr * bool =
// TODO: serialization format for DateTime etc // TODO: serialization format for DateTime etc
match fieldType with match fieldType with
| DateOnly | DateOnly
| DateTime | DateTime
| NumberType _ | NumberType _
| Measure _
| PrimitiveType _ | PrimitiveType _
| Guid | Guid
| Uri -> | Uri ->
// JsonValue.Create<type> // JsonValue.Create<type>
SynExpr.TypeApp ( SynExpr.createLongIdent [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonValue" ; "Create" ]
SynExpr.createLongIdent [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonValue" ; "Create" ], |> SynExpr.typeApp [ fieldType ]
range0, |> fun e -> e, false
[ fieldType ], | DateTimeOffset ->
[], // fun field -> field.ToString("o") |> JsonValue.Create<string>
Some range0, let create =
range0, SynExpr.createLongIdent [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonValue" ; "Create" ]
range0 |> SynExpr.typeApp [ SynType.named "string" ]
)
SynExpr.createIdent "field"
|> SynExpr.callMethodArg "ToString" (SynExpr.CreateConst "o")
|> SynExpr.pipeThroughFunction create
|> SynExpr.createLambda "field"
|> fun e -> e, false
| NullableType ty ->
// fun field -> if field.HasValue then {serializeNode ty} field.Value else JsonValue.Create null
let inner, innerIsJsonNode = serializeNode ty
SynExpr.applyFunction inner (SynExpr.createLongIdent [ "field" ; "Value" ])
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|> SynExpr.ifThenElse (SynExpr.createLongIdent [ "field" ; "HasValue" ]) (jsonNull ())
|> SynExpr.createLambda "field"
|> fun e -> e, innerIsJsonNode
| OptionType ty -> | OptionType ty ->
// fun field -> match field with | None -> JsonValue.Create null | Some v -> {serializeNode ty} field // fun field -> match field with | None -> JsonValue.Create null | Some v -> {serializeNode ty} field
let noneClause = let noneClause = jsonNull () |> SynMatchClause.create (SynPat.named "None")
// The absolutely galaxy-brained implementation of JsonValue has `JsonValue.Parse "null"`
// identically equal to null. We have to work around this later, but we might as well just
// be efficient here and whip up the null directly.
SynExpr.createNull ()
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|> SynMatchClause.create (SynPat.named "None")
let someClause = let someClause =
SynExpr.applyFunction (serializeNode ty) (SynExpr.createIdent "field") let inner, innerIsJsonNode = serializeNode ty
|> SynExpr.paren let target = SynExpr.applyFunction inner (SynExpr.createIdent "field")
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
if innerIsJsonNode then
target
else
target
|> SynExpr.paren
|> SynExpr.upcast' (SynType.createLongIdent' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ])
|> SynMatchClause.create ( |> SynMatchClause.create (
SynPat.identWithArgs [ Ident.create "Some" ] (SynArgPats.create [ Ident.create "field" ]) SynPat.identWithArgs [ Ident.create "Some" ] (SynArgPats.create [ Ident.create "field" ])
) )
@@ -55,6 +79,7 @@ module internal JsonSerializeGenerator =
[ noneClause ; someClause ] [ noneClause ; someClause ]
|> SynExpr.createMatch (SynExpr.createIdent "field") |> SynExpr.createMatch (SynExpr.createIdent "field")
|> SynExpr.createLambda "field" |> SynExpr.createLambda "field"
|> fun e -> e, true
| ArrayType ty | ArrayType ty
| ListType ty -> | ListType ty ->
// fun field -> // fun field ->
@@ -71,7 +96,7 @@ module internal JsonSerializeGenerator =
SynExpr.createIdent "field", SynExpr.createIdent "field",
SynExpr.applyFunction SynExpr.applyFunction
(SynExpr.createLongIdent [ "arr" ; "Add" ]) (SynExpr.createLongIdent [ "arr" ; "Add" ])
(SynExpr.paren (SynExpr.applyFunction (serializeNode ty) (SynExpr.createIdent "mem"))), (SynExpr.paren (SynExpr.applyFunction (fst (serializeNode ty)) (SynExpr.createIdent "mem"))),
range0 range0
) )
SynExpr.createIdent "arr" SynExpr.createIdent "arr"
@@ -84,6 +109,7 @@ module internal JsonSerializeGenerator =
|> SynBinding.basic [ Ident.create "arr" ] [] |> SynBinding.basic [ Ident.create "arr" ] []
] ]
|> SynExpr.createLambda "field" |> SynExpr.createLambda "field"
|> fun e -> e, false
| IDictionaryType (_keyType, valueType) | IDictionaryType (_keyType, valueType)
| DictionaryType (_keyType, valueType) | DictionaryType (_keyType, valueType)
| IReadOnlyDictionaryType (_keyType, valueType) | IReadOnlyDictionaryType (_keyType, valueType)
@@ -111,7 +137,7 @@ module internal JsonSerializeGenerator =
[ [
SynExpr.createLongIdent [ "key" ; "ToString" ] SynExpr.createLongIdent [ "key" ; "ToString" ]
|> SynExpr.applyTo (SynExpr.CreateConst ()) |> SynExpr.applyTo (SynExpr.CreateConst ())
SynExpr.applyFunction (serializeNode valueType) (SynExpr.createIdent "value") SynExpr.applyFunction (fst (serializeNode valueType)) (SynExpr.createIdent "value")
]), ]),
range0 range0
) )
@@ -125,6 +151,7 @@ module internal JsonSerializeGenerator =
|> SynBinding.basic [ Ident.create "ret" ] [] |> SynBinding.basic [ Ident.create "ret" ] []
] ]
|> SynExpr.createLambda "field" |> SynExpr.createLambda "field"
|> fun e -> e, false
| _ -> | _ ->
// {type}.toJsonNode // {type}.toJsonNode
let typeName = let typeName =
@@ -132,16 +159,17 @@ module internal JsonSerializeGenerator =
| SynType.LongIdent ident -> ident.LongIdent | SynType.LongIdent ident -> ident.LongIdent
| _ -> failwith $"Unrecognised type: %+A{fieldType}" | _ -> failwith $"Unrecognised type: %+A{fieldType}"
SynExpr.createLongIdent' (typeName @ [ Ident.create "toJsonNode" ]) SynExpr.createLongIdent' (typeName @ [ Ident.create "toJsonNode" ]), true
/// propertyName is probably a string literal, but it could be a [<Literal>] variable /// propertyName is probably a string literal, but it could be a [<Literal>] variable
/// `node.Add ({propertyName}, {toJsonNode})` /// `node.Add ({propertyName}, {toJsonNode})`
let createSerializeRhsRecord (propertyName : SynExpr) (fieldId : Ident) (fieldType : SynType) : SynExpr = let createSerializeRhsRecord (propertyName : SynExpr) (fieldId : Ident) (fieldType : SynType) : SynExpr =
[ [
propertyName propertyName
SynExpr.applyFunction SynExpr.pipeThroughFunction
(serializeNode fieldType) (fst (serializeNode fieldType))
(SynExpr.createLongIdent' [ Ident.create "input" ; fieldId ]) (SynExpr.createLongIdent' [ Ident.create "input" ; fieldId ])
|> SynExpr.paren
] ]
|> SynExpr.tuple |> SynExpr.tuple
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "node" ; "Add" ]) |> SynExpr.applyFunction (SynExpr.createLongIdent [ "node" ; "Add" ])
@@ -228,8 +256,7 @@ module internal JsonSerializeGenerator =
|> SynBinding.withXmlDoc xmlDoc |> SynBinding.withXmlDoc xmlDoc
|> SynModuleDecl.createLet |> SynModuleDecl.createLet
let recordModule (spec : JsonSerializeOutputSpec) (typeName : LongIdent) (fields : SynField list) = let recordModule (spec : JsonSerializeOutputSpec) (_typeName : LongIdent) (fields : SynField list) =
let inputArg = Ident.create "input"
let fields = fields |> List.map SynField.extractWithIdent let fields = fields |> List.map SynField.extractWithIdent
fields fields
@@ -239,7 +266,6 @@ module internal JsonSerializeGenerator =
) )
|> SynExpr.sequential |> SynExpr.sequential
|> fun expr -> SynExpr.Do (expr, range0) |> fun expr -> SynExpr.Do (expr, range0)
|> scaffolding spec typeName inputArg
let unionModule (spec : JsonSerializeOutputSpec) (typeName : LongIdent) (cases : SynUnionCase list) = let unionModule (spec : JsonSerializeOutputSpec) (typeName : LongIdent) (cases : SynUnionCase list) =
let inputArg = Ident.create "input" let inputArg = Ident.create "input"
@@ -285,7 +311,7 @@ module internal JsonSerializeGenerator =
let propertyName = getPropertyName (Option.get fieldData.Ident) fieldData.Attrs let propertyName = getPropertyName (Option.get fieldData.Ident) fieldData.Attrs
let node = let node =
SynExpr.applyFunction (serializeNode fieldData.Type) (SynExpr.createIdent' caseName) SynExpr.applyFunction (fst (serializeNode fieldData.Type)) (SynExpr.createIdent' caseName)
[ propertyName ; node ] [ propertyName ; node ]
|> SynExpr.tuple |> SynExpr.tuple
@@ -312,7 +338,68 @@ module internal JsonSerializeGenerator =
SynMatchClause.create pattern action SynMatchClause.create pattern action
) )
|> SynExpr.createMatch (SynExpr.createIdent' inputArg) |> SynExpr.createMatch (SynExpr.createIdent' inputArg)
|> scaffolding spec typeName inputArg
let enumModule
(spec : JsonSerializeOutputSpec)
(typeName : LongIdent)
(cases : (Ident * SynExpr) list)
: SynModuleDecl
=
let fail =
SynExpr.CreateConst "Unrecognised value for enum: %O"
|> SynExpr.applyFunction (SynExpr.createIdent "sprintf")
|> SynExpr.applyTo (SynExpr.createIdent "v")
|> SynExpr.paren
|> SynExpr.applyFunction (SynExpr.createIdent "failwith")
let body =
cases
|> List.map (fun (caseName, value) ->
value
|> SynExpr.applyFunction (
SynExpr.createLongIdent [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonValue" ; "Create" ]
)
|> SynMatchClause.create (SynPat.identWithArgs (typeName @ [ caseName ]) (SynArgPats.create []))
)
|> fun l -> l @ [ SynMatchClause.create (SynPat.named "v") fail ]
|> SynExpr.createMatch (SynExpr.createIdent "input")
let xmlDoc = PreXmlDoc.create "Serialize to a JSON node"
let returnInfo =
SynLongIdent.createS' [ "System" ; "Text" ; "Json" ; "Nodes" ; "JsonNode" ]
|> SynType.LongIdent
let functionName = Ident.create "toJsonNode"
let pattern =
SynPat.named "input"
|> SynPat.annotateType (SynType.LongIdent (SynLongIdent.create typeName))
if spec.ExtensionMethods then
let componentInfo =
SynComponentInfo.createLong typeName
|> SynComponentInfo.withDocString (PreXmlDoc.create "Extension methods for JSON parsing")
let memberDef =
body
|> SynBinding.basic [ functionName ] [ pattern ]
|> SynBinding.withXmlDoc xmlDoc
|> SynBinding.withReturnAnnotation returnInfo
|> SynMemberDefn.staticMember
let containingType =
SynTypeDefnRepr.augmentation ()
|> SynTypeDefn.create componentInfo
|> SynTypeDefn.withMemberDefns [ memberDef ]
SynModuleDecl.Types ([ containingType ], range0)
else
body
|> SynBinding.basic [ functionName ] [ pattern ]
|> SynBinding.withReturnAnnotation returnInfo
|> SynBinding.withXmlDoc xmlDoc
|> SynModuleDecl.createLet
let createModule let createModule
(namespaceId : LongIdent) (namespaceId : LongIdent)
@@ -368,14 +455,23 @@ module internal JsonSerializeGenerator =
let decls = let decls =
match synTypeDefnRepr with match synTypeDefnRepr with
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Record (_accessibility, recordFields, _range), _) -> | SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Record (_accessibility, recordFields, _range), _) ->
[ recordModule spec ident recordFields ] recordModule spec ident recordFields
|> scaffolding spec ident (Ident.create "input")
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Union (_accessibility, unionFields, _range), _) -> | SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Union (_accessibility, unionFields, _range), _) ->
[ unionModule spec ident unionFields ] unionModule spec ident unionFields
| _ -> failwithf "Only record types currently supported." |> scaffolding spec ident (Ident.create "input")
| SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.Enum (cases, _range), _) ->
cases
|> List.map (fun c ->
match c with
| SynEnumCase.SynEnumCase (_, SynIdent.SynIdent (ident, _), value, _, _, _) -> ident, value
)
|> enumModule spec ident
| ty -> failwithf "Unsupported type: got %O" ty
[ [
yield! opens |> List.map SynModuleDecl.openAny yield! opens |> List.map SynModuleDecl.openAny
yield SynModuleDecl.nestedModule info decls yield decls |> List.singleton |> SynModuleDecl.nestedModule info
] ]
|> SynModuleOrNamespace.createNamespace namespaceId |> SynModuleOrNamespace.createNamespace namespaceId
@@ -393,20 +489,21 @@ type JsonSerializeGenerator () =
let ast, _ = let ast, _ =
Ast.fromFilename context.InputFilename |> Async.RunSynchronously |> Array.head Ast.fromFilename context.InputFilename |> Async.RunSynchronously |> Array.head
let recordsAndUnions = let relevantTypes =
Ast.extractTypeDefn ast Ast.extractTypeDefn ast
|> List.map (fun (name, defns) -> |> List.map (fun (name, defns) ->
defns defns
|> List.choose (fun defn -> |> List.choose (fun defn ->
if Ast.isRecord defn then Some defn if Ast.isRecord defn then Some defn
elif Ast.isDu defn then Some defn elif Ast.isDu defn then Some defn
elif AstHelper.isEnum defn then Some defn
else None else None
) )
|> fun defns -> name, defns |> fun defns -> name, defns
) )
let namespaceAndTypes = let namespaceAndTypes =
recordsAndUnions relevantTypes
|> List.choose (fun (ns, types) -> |> List.choose (fun (ns, types) ->
types types
|> List.choose (fun typeDef -> |> List.choose (fun typeDef ->

View File

@@ -0,0 +1,24 @@
namespace WoofWare.Myriad.Plugins
open Fantomas.FCS.Syntax
[<RequireQualifiedAccess>]
module internal Measure =
let getLanguagePrimitivesMeasure (typeName : LongIdent) : SynExpr =
match typeName |> List.map _.idText with
| [ "System" ; "Single" ] -> [ "LanguagePrimitives" ; "Float32WithMeasure" ]
| [ "System" ; "Double" ] -> [ "LanguagePrimitives" ; "FloatWithMeasure" ]
| [ "System" ; "Byte" ] -> [ "LanguagePrimitives" ; "ByteWithMeasure" ]
| [ "System" ; "SByte" ] -> [ "LanguagePrimitives" ; "SByteWithMeasure" ]
| [ "System" ; "Int16" ] -> [ "LanguagePrimitives" ; "Int16WithMeasure" ]
| [ "System" ; "Int32" ] -> [ "LanguagePrimitives" ; "Int32WithMeasure" ]
| [ "System" ; "Int64" ] -> [ "LanguagePrimitives" ; "Int64WithMeasure" ]
| [ "System" ; "UInt16" ] -> [ "LanguagePrimitives" ; "UInt16WithMeasure" ]
| [ "System" ; "UInt32" ] -> [ "LanguagePrimitives" ; "UInt32WithMeasure" ]
| [ "System" ; "UInt64" ] -> [ "LanguagePrimitives" ; "UInt64WithMeasure" ]
| l ->
let l = String.concat "." l
failwith $"unrecognised type for measure: %s{l}"
|> SynExpr.createLongIdent

View File

@@ -26,5 +26,7 @@ module internal Primitives =
| "uint64" -> [ "System" ; "UInt64" ] |> Some | "uint64" -> [ "System" ; "UInt64" ] |> Some
| "char" -> [ "System" ; "Char" ] |> Some | "char" -> [ "System" ; "Char" ] |> Some
| "decimal" -> [ "System" ; "Decimal" ] |> Some | "decimal" -> [ "System" ; "Decimal" ] |> Some
| "string" -> [ "System" ; "String" ] |> Some
| "bool" -> [ "System" ; "Boolean" ] |> Some
| _ -> None | _ -> None
|> Option.map (List.map (fun i -> (Ident (i, range0)))) |> Option.map (List.map (fun i -> (Ident (i, range0))))

View File

@@ -42,6 +42,7 @@ module internal RemoveOptionsGenerator =
(accessibility : SynAccess option) (accessibility : SynAccess option)
(generics : SynTyparDecls option) (generics : SynTyparDecls option)
(fields : SynField list) (fields : SynField list)
: SynModuleDecl
= =
let fields : SynField list = fields |> List.map removeOption let fields : SynField list = fields |> List.map removeOption
let name = Ident.create "Short" let name = Ident.create "Short"
@@ -54,6 +55,7 @@ module internal RemoveOptionsGenerator =
XmlDoc = xmlDoc XmlDoc = xmlDoc
Generics = generics Generics = generics
Accessibility = accessibility Accessibility = accessibility
Attributes = []
} }
let typeDecl = AstHelper.defineRecordType record let typeDecl = AstHelper.defineRecordType record
@@ -91,7 +93,7 @@ module internal RemoveOptionsGenerator =
) )
| _ -> accessor | _ -> accessor
(SynLongIdent.createI fieldData.Ident, true), Some body SynLongIdent.createI fieldData.Ident, body
) )
|> AstHelper.instantiateRecord |> AstHelper.instantiateRecord

View File

@@ -0,0 +1,15 @@
namespace WoofWare.Myriad.Plugins
open Fantomas.FCS.Syntax
open Fantomas.FCS.Text.Range
[<RequireQualifiedAccess>]
module internal SynAttributes =
let ofAttrs (attrs : SynAttribute list) : SynAttributes =
attrs
|> List.map (fun a ->
{
Attributes = [ a ]
Range = range0
}
)

View File

@@ -62,6 +62,35 @@ module internal SynBinding =
triviaZero false triviaZero false
) )
let withMutability (mut : bool) (binding : SynBinding) : SynBinding =
match binding with
| SynBinding (pat, kind, inl, _, attrs, xml, valData, headPat, returnInfo, expr, range, debugPoint, trivia) ->
SynBinding (pat, kind, inl, mut, attrs, xml, valData, headPat, returnInfo, expr, range, debugPoint, trivia)
let withRecursion (isRec : bool) (binding : SynBinding) : SynBinding =
match binding with
| SynBinding (pat, kind, inl, mut, attrs, xml, valData, headPat, returnInfo, expr, range, debugPoint, trivia) ->
let trivia =
{ trivia with
LeadingKeyword =
match trivia.LeadingKeyword with
| SynLeadingKeyword.Let _ ->
if isRec then
SynLeadingKeyword.LetRec (range0, range0)
else
trivia.LeadingKeyword
| SynLeadingKeyword.LetRec _ ->
if isRec then
trivia.LeadingKeyword
else
trivia.LeadingKeyword
| existing ->
failwith
$"WoofWare.Myriad doesn't yet let you adjust the recursion modifier on a binding with modifier %O{existing}"
}
SynBinding (pat, kind, inl, mut, attrs, xml, valData, headPat, returnInfo, expr, range, debugPoint, trivia)
let withAccessibility (acc : SynAccess option) (binding : SynBinding) : SynBinding = let withAccessibility (acc : SynAccess option) (binding : SynBinding) : SynBinding =
match binding with match binding with
| SynBinding (_, kind, inl, mut, attrs, xml, valData, headPat, returnInfo, expr, range, debugPoint, trivia) -> | SynBinding (_, kind, inl, mut, attrs, xml, valData, headPat, returnInfo, expr, range, debugPoint, trivia) ->

View File

@@ -13,6 +13,13 @@ module internal SynExprExtensions =
static member CreateConst () : SynExpr = SynExpr.Const (SynConst.Unit, range0) static member CreateConst () : SynExpr = SynExpr.Const (SynConst.Unit, range0)
static member CreateConst (b : bool) : SynExpr = SynExpr.Const (SynConst.Bool b, range0)
static member CreateConst (c : char) : SynExpr =
// apparent Myriad bug: `IndexOf '?'` gets formatted as `IndexOf ?` which is clearly wrong
SynExpr.CreateApp (SynExpr.Ident (Ident.Create "char"), SynExpr.CreateConst (int c))
|> fun e -> SynExpr.Paren (e, range0, Some range0, range0)
static member CreateConst (i : int32) : SynExpr = static member CreateConst (i : int32) : SynExpr =
SynExpr.Const (SynConst.Int32 i, range0) SynExpr.Const (SynConst.Int32 i, range0)
@@ -87,53 +94,65 @@ module internal SynExpr =
) )
|> applyTo b |> applyTo b
/// {a} * {b}
let times (a : SynExpr) (b : SynExpr) =
SynExpr.CreateAppInfix (
SynExpr.CreateLongIdent (
SynLongIdent.SynLongIdent (
Ident.CreateLong "op_Multiply",
[],
[ Some (IdentTrivia.OriginalNotation "*") ]
)
),
a
)
|> applyTo b
let rec stripOptionalParen (expr : SynExpr) : SynExpr = let rec stripOptionalParen (expr : SynExpr) : SynExpr =
match expr with match expr with
| SynExpr.Paren (expr, _, _, _) -> stripOptionalParen expr | SynExpr.Paren (expr, _, _, _) -> stripOptionalParen expr
| expr -> expr | expr -> expr
/// {obj}.{meth} {arg} let dotGet (field : string) (obj : SynExpr) : SynExpr =
let callMethodArg (meth : string) (arg : SynExpr) (obj : SynExpr) : SynExpr =
SynExpr.DotGet ( SynExpr.DotGet (
obj, obj,
range0, range0,
SynLongIdent.SynLongIdent (id = [ Ident.create meth ], dotRanges = [], trivia = [ None ]), SynLongIdent.SynLongIdent (id = [ Ident.create field ], dotRanges = [], trivia = [ None ]),
range0 range0
) )
|> applyTo arg
/// {obj}.{meth} {arg}
let callMethodArg (meth : string) (arg : SynExpr) (obj : SynExpr) : SynExpr = dotGet meth obj |> applyTo arg
/// {obj}.{meth}() /// {obj}.{meth}()
let callMethod (meth : string) (obj : SynExpr) : SynExpr = let callMethod (meth : string) (obj : SynExpr) : SynExpr =
callMethodArg meth (SynExpr.CreateConst ()) obj callMethodArg meth (SynExpr.CreateConst ()) obj
let typeApp (types : SynType list) (operand : SynExpr) =
SynExpr.TypeApp (operand, range0, types, List.replicate (types.Length - 1) range0, Some range0, range0, range0)
let callGenericMethod (meth : string) (ty : LongIdent) (obj : SynExpr) : SynExpr = let callGenericMethod (meth : string) (ty : LongIdent) (obj : SynExpr) : SynExpr =
SynExpr.TypeApp ( SynExpr.DotGet (obj, range0, SynLongIdent.createS meth, range0)
SynExpr.DotGet (obj, range0, SynLongIdent.createS meth, range0), |> typeApp [ SynType.LongIdent (SynLongIdent.create ty) ]
range0,
[ SynType.LongIdent (SynLongIdent.create ty) ],
[],
Some range0,
range0,
range0
)
|> applyTo (SynExpr.CreateConst ()) |> applyTo (SynExpr.CreateConst ())
/// {obj}.{meth}<ty>() /// {obj}.{meth}<ty>()
let callGenericMethod' (meth : string) (ty : string) (obj : SynExpr) : SynExpr = let callGenericMethod' (meth : string) (ty : string) (obj : SynExpr) : SynExpr =
SynExpr.TypeApp ( SynExpr.DotGet (obj, range0, SynLongIdent.createS meth, range0)
SynExpr.DotGet (obj, range0, SynLongIdent.createS meth, range0), |> typeApp [ SynType.createLongIdent' [ ty ] ]
range0,
[ SynType.createLongIdent' [ ty ] ],
[],
Some range0,
range0,
range0
)
|> applyTo (SynExpr.CreateConst ()) |> applyTo (SynExpr.CreateConst ())
let inline index (property : SynExpr) (obj : SynExpr) : SynExpr = let inline index (property : SynExpr) (obj : SynExpr) : SynExpr =
SynExpr.DotIndexedGet (obj, property, range0, range0) SynExpr.DotIndexedGet (obj, property, range0, range0)
let inline arrayIndexRange (start : SynExpr option) (endRange : SynExpr option) (arr : SynExpr) : SynExpr =
SynExpr.DotIndexedGet (
arr,
(SynExpr.IndexRange (start, range0, endRange, range0, range0, range0)),
range0,
range0
)
let inline paren (e : SynExpr) : SynExpr = let inline paren (e : SynExpr) : SynExpr =
SynExpr.Paren (e, range0, Some range0, range0) SynExpr.Paren (e, range0, Some range0, range0)
@@ -198,6 +217,18 @@ module internal SynExpr =
pipeThroughFunction lambda body pipeThroughFunction lambda body
let inline createForEach (pat : SynPat) (enumExpr : SynExpr) (body : SynExpr) : SynExpr =
SynExpr.ForEach (
DebugPointAtFor.No,
DebugPointAtInOrTo.No,
SeqExprOnly.SeqExprOnly false,
true,
pat,
enumExpr,
body,
range0
)
let inline createLet (bindings : SynBinding list) (body : SynExpr) : SynExpr = let inline createLet (bindings : SynBinding list) (body : SynExpr) : SynExpr =
SynExpr.LetOrUse (false, false, bindings, body, range0, SynExprLetOrUseTrivia.empty) SynExpr.LetOrUse (false, false, bindings, body, range0, SynExprLetOrUseTrivia.empty)
@@ -292,9 +323,37 @@ module internal SynExpr =
/// {y} > {x} /// {y} > {x}
let greaterThan (x : SynExpr) (y : SynExpr) : SynExpr = let greaterThan (x : SynExpr) (y : SynExpr) : SynExpr =
SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.ge, y) |> applyTo x SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.gt, y) |> applyTo x
/// {y} < {x}
let lessThan (x : SynExpr) (y : SynExpr) : SynExpr =
SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.lt, y) |> applyTo x
/// {y} >= {x} /// {y} >= {x}
let greaterThanOrEqual (x : SynExpr) (y : SynExpr) : SynExpr = let greaterThanOrEqual (x : SynExpr) (y : SynExpr) : SynExpr =
SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.geq, y) SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.geq, y)
|> applyTo x |> applyTo x
/// {y} <= {x}
let lessThanOrEqual (x : SynExpr) (y : SynExpr) : SynExpr =
SynExpr.CreateAppInfix (SynExpr.CreateLongIdent SynLongIdent.leq, y)
|> applyTo x
/// {x} :: {y}
let listCons (x : SynExpr) (y : SynExpr) : SynExpr =
SynExpr.CreateAppInfix (
SynExpr.LongIdent (
false,
SynLongIdent.SynLongIdent (
[ Ident.create "op_ColonColon" ],
[],
[ Some (IdentTrivia.OriginalNotation "::") ]
),
None,
range0
),
tupleNoParen [ x ; y ]
)
|> paren
let assign (lhs : SynLongIdent) (rhs : SynExpr) : SynExpr = SynExpr.LongIdentSet (lhs, rhs, range0)

View File

@@ -14,9 +14,19 @@ module internal SynLongIdent =
[ Some (IdentTrivia.OriginalNotation ">=") ] [ Some (IdentTrivia.OriginalNotation ">=") ]
) )
let ge = let leq =
SynLongIdent.SynLongIdent (
[ Ident.create "op_LessThanOrEqual" ],
[],
[ Some (IdentTrivia.OriginalNotation "<=") ]
)
let gt =
SynLongIdent.SynLongIdent ([ Ident.create "op_GreaterThan" ], [], [ Some (IdentTrivia.OriginalNotation ">") ]) SynLongIdent.SynLongIdent ([ Ident.create "op_GreaterThan" ], [], [ Some (IdentTrivia.OriginalNotation ">") ])
let lt =
SynLongIdent.SynLongIdent ([ Ident.create "op_LessThan" ], [], [ Some (IdentTrivia.OriginalNotation "<") ])
let sub = let sub =
SynLongIdent.SynLongIdent ([ Ident.create "op_Subtraction" ], [], [ Some (IdentTrivia.OriginalNotation "-") ]) SynLongIdent.SynLongIdent ([ Ident.create "op_Subtraction" ], [], [ Some (IdentTrivia.OriginalNotation "-") ])
@@ -70,6 +80,18 @@ module internal SynLongIdent =
// TODO: consider Microsoft.FSharp.Option or whatever it is // TODO: consider Microsoft.FSharp.Option or whatever it is
| _ -> false | _ -> false
let isChoice (ident : SynLongIdent) : bool =
match ident.LongIdent with
| [ i ] when System.String.Equals (i.idText, "Choice", System.StringComparison.Ordinal) -> true
// TODO: consider Microsoft.FSharp.Choice or whatever it is
| _ -> false
let isNullable (ident : SynLongIdent) : bool =
match ident.LongIdent |> List.map _.idText with
| [ "System" ; "Nullable" ]
| [ "Nullable" ] -> true
| _ -> false
let isResponse (ident : SynLongIdent) : bool = let isResponse (ident : SynLongIdent) : bool =
match ident.LongIdent |> List.map _.idText with match ident.LongIdent |> List.map _.idText with
| [ "Response" ] | [ "Response" ]

View File

@@ -14,6 +14,8 @@ module internal SynModuleDecl =
let inline createLet (binding : SynBinding) : SynModuleDecl = createLets [ binding ] let inline createLet (binding : SynBinding) : SynModuleDecl = createLets [ binding ]
let inline createTypes (tys : SynTypeDefn list) : SynModuleDecl = SynModuleDecl.Types (tys, range0)
let nestedModule (info : SynComponentInfo) (decls : SynModuleDecl list) : SynModuleDecl = let nestedModule (info : SynComponentInfo) (decls : SynModuleDecl list) : SynModuleDecl =
SynModuleDecl.NestedModule ( SynModuleDecl.NestedModule (
info, info,

View File

@@ -33,3 +33,17 @@ module internal SynPat =
let unit = createConst SynConst.Unit let unit = createConst SynConst.Unit
let createNull = SynPat.Null range0 let createNull = SynPat.Null range0
let emptyList = SynPat.ArrayOrList (false, [], range0)
let listCons (lhs : SynPat) (rhs : SynPat) =
SynPat.ListCons (
lhs,
rhs,
range0,
{
ColonColonRange = range0
}
)
let emptyArray = SynPat.ArrayOrList (true, [], range0)

View File

@@ -1,56 +1,9 @@
namespace WoofWare.Myriad.Plugins namespace WoofWare.Myriad.Plugins
open System
open Fantomas.FCS.Syntax open Fantomas.FCS.Syntax
open Fantomas.FCS.Text.Range open Fantomas.FCS.Text.Range
[<RequireQualifiedAccess>]
module internal SynType =
let rec stripOptionalParen (ty : SynType) : SynType =
match ty with
| SynType.Paren (ty, _) -> stripOptionalParen ty
| ty -> ty
let inline createLongIdent (ident : LongIdent) : SynType =
SynType.LongIdent (SynLongIdent.create ident)
let inline createLongIdent' (ident : string list) : SynType =
SynType.LongIdent (SynLongIdent.createS' ident)
let inline named (name : string) = createLongIdent' [ name ]
let inline app' (name : SynType) (args : SynType list) : SynType =
if args.IsEmpty then
failwith "Type cannot be applied to no arguments"
SynType.App (name, Some range0, args, List.replicate (args.Length - 1) range0, Some range0, false, range0)
let inline app (name : string) (args : SynType list) : SynType = app' (named name) args
let inline appPostfix (name : string) (arg : SynType) : SynType =
SynType.App (named name, None, [ arg ], [], None, true, range0)
let inline funFromDomain (domain : SynType) (range : SynType) : SynType =
SynType.Fun (
domain,
range,
range0,
{
ArrowRange = range0
}
)
let inline signatureParamOfType (ty : SynType) (name : Ident option) : SynType =
SynType.SignatureParameter ([], false, name, ty, range0)
let inline var (ty : SynTypar) : SynType = SynType.Var (ty, range0)
let unit : SynType = named "unit"
let int : SynType = named "int"
/// Given ['a1, 'a2] and 'ret, returns 'a1 -> 'a2 -> 'ret.
let toFun (inputs : SynType list) (ret : SynType) : SynType =
(ret, List.rev inputs) ||> List.fold (fun ty input -> funFromDomain input ty)
[<AutoOpen>] [<AutoOpen>]
module internal SynTypePatterns = module internal SynTypePatterns =
let (|OptionType|_|) (fieldType : SynType) = let (|OptionType|_|) (fieldType : SynType) =
@@ -59,6 +12,17 @@ module internal SynTypePatterns =
Some innerType Some innerType
| _ -> None | _ -> None
let (|ChoiceType|_|) (fieldType : SynType) =
match fieldType with
| SynType.App (SynType.LongIdent ident, _, inner, _, _, _, _) when SynLongIdent.isChoice ident -> Some inner
| _ -> None
let (|NullableType|_|) (fieldType : SynType) =
match fieldType with
| SynType.App (SynType.LongIdent ident, _, [ innerType ], _, _, _, _) when SynLongIdent.isNullable ident ->
Some innerType
| _ -> None
let (|UnitType|_|) (fieldType : SynType) : unit option = let (|UnitType|_|) (fieldType : SynType) : unit option =
match fieldType with match fieldType with
| SynType.LongIdent ident when SynLongIdent.isUnit ident -> Some () | SynType.LongIdent ident when SynLongIdent.isUnit ident -> Some ()
@@ -193,10 +157,30 @@ module internal SynTypePatterns =
match fieldType with match fieldType with
| SynType.LongIdent ident -> | SynType.LongIdent ident ->
match ident.LongIdent with match ident.LongIdent with
| [ i ] -> [ "string" ; "float" ; "int" ; "bool" ] |> List.tryFind (fun s -> s = i.idText) | [ i ] ->
// We won't bother with the case that the user has done e.g. `Single` (relying on `System` being open).
match Primitives.qualifyType i.idText with
| Some qualified ->
match i.idText with
| "char"
| "string" -> None
| _ -> Some qualified
| None -> None
| _ -> None | _ -> None
| _ -> None | _ -> None
/// Returns the name of the measure, and the outer type.
let (|Measure|_|) (fieldType : SynType) : (Ident * LongIdent) option =
match fieldType with
| SynType.App (NumberType outer,
_,
[ SynType.LongIdent (SynLongIdent.SynLongIdent ([ ident ], _, _)) ],
_,
_,
_,
_) -> Some (ident, outer)
| _ -> None
let (|DateOnly|_|) (fieldType : SynType) = let (|DateOnly|_|) (fieldType : SynType) =
match fieldType with match fieldType with
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) -> | SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
@@ -215,6 +199,15 @@ module internal SynTypePatterns =
| _ -> None | _ -> None
| _ -> None | _ -> None
let (|DateTimeOffset|_|) (fieldType : SynType) =
match fieldType with
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
match ident |> List.map (fun i -> i.idText) with
| [ "System" ; "DateTimeOffset" ]
| [ "DateTimeOffset" ] -> Some ()
| _ -> None
| _ -> None
let (|Uri|_|) (fieldType : SynType) = let (|Uri|_|) (fieldType : SynType) =
match fieldType with match fieldType with
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) -> | SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
@@ -237,3 +230,169 @@ module internal SynTypePatterns =
| _ -> failwithf "Expected Task to be applied to exactly one arg, but got: %+A" args | _ -> failwithf "Expected Task to be applied to exactly one arg, but got: %+A" args
| _ -> None | _ -> None
| _ -> None | _ -> None
let (|DirectoryInfo|_|) (fieldType : SynType) =
match fieldType with
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
match ident |> List.map (fun i -> i.idText) with
| [ "System" ; "IO" ; "DirectoryInfo" ]
| [ "IO" ; "DirectoryInfo" ]
| [ "DirectoryInfo" ] -> Some ()
| _ -> None
| _ -> None
let (|FileInfo|_|) (fieldType : SynType) =
match fieldType with
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
match ident |> List.map (fun i -> i.idText) with
| [ "System" ; "IO" ; "FileInfo" ]
| [ "IO" ; "FileInfo" ]
| [ "FileInfo" ] -> Some ()
| _ -> None
| _ -> None
[<RequireQualifiedAccess>]
module internal SynType =
let rec stripOptionalParen (ty : SynType) : SynType =
match ty with
| SynType.Paren (ty, _) -> stripOptionalParen ty
| ty -> ty
let inline createLongIdent (ident : LongIdent) : SynType =
SynType.LongIdent (SynLongIdent.create ident)
let inline createLongIdent' (ident : string list) : SynType =
SynType.LongIdent (SynLongIdent.createS' ident)
let inline named (name : string) = createLongIdent' [ name ]
let inline app' (name : SynType) (args : SynType list) : SynType =
if args.IsEmpty then
failwith "Type cannot be applied to no arguments"
SynType.App (name, Some range0, args, List.replicate (args.Length - 1) range0, Some range0, false, range0)
let inline app (name : string) (args : SynType list) : SynType = app' (named name) args
let inline appPostfix (name : string) (arg : SynType) : SynType =
SynType.App (named name, None, [ arg ], [], None, true, range0)
let inline appPostfix' (name : string list) (arg : SynType) : SynType =
SynType.App (createLongIdent' name, None, [ arg ], [], None, true, range0)
let inline funFromDomain (domain : SynType) (range : SynType) : SynType =
SynType.Fun (
domain,
range,
range0,
{
ArrowRange = range0
}
)
let inline signatureParamOfType (ty : SynType) (name : Ident option) : SynType =
SynType.SignatureParameter ([], false, name, ty, range0)
let inline var (ty : SynTypar) : SynType = SynType.Var (ty, range0)
let unit : SynType = named "unit"
let int : SynType = named "int"
let anon : SynType = SynType.Anon range0
let string : SynType = named "string"
/// Given ['a1, 'a2] and 'ret, returns 'a1 -> 'a2 -> 'ret.
let toFun (inputs : SynType list) (ret : SynType) : SynType =
(ret, List.rev inputs) ||> List.fold (fun ty input -> funFromDomain input ty)
/// Guess whether the types are equal. We err on the side of saying "no, they're different".
let rec provablyEqual (ty1 : SynType) (ty2 : SynType) : bool =
if Object.ReferenceEquals (ty1, ty2) then
true
else
match ty1 with
| PrimitiveType t1 ->
match ty2 with
| PrimitiveType t2 -> (t1 |> List.map _.idText) = (t2 |> List.map _.idText)
| _ -> false
| OptionType t1 ->
match ty2 with
| OptionType t2 -> provablyEqual t1 t2
| _ -> false
| NullableType t1 ->
match ty2 with
| NullableType t2 -> provablyEqual t1 t2
| _ -> false
| ChoiceType t1 ->
match ty2 with
| ChoiceType t2 ->
t1.Length = t2.Length
&& List.forall (fun (a, b) -> provablyEqual a b) (List.zip t1 t2)
| _ -> false
| DictionaryType (k1, v1) ->
match ty2 with
| DictionaryType (k2, v2) -> provablyEqual k1 k2 && provablyEqual v1 v2
| _ -> false
| IDictionaryType (k1, v1) ->
match ty2 with
| IDictionaryType (k2, v2) -> provablyEqual k1 k2 && provablyEqual v1 v2
| _ -> false
| IReadOnlyDictionaryType (k1, v1) ->
match ty2 with
| IReadOnlyDictionaryType (k2, v2) -> provablyEqual k1 k2 && provablyEqual v1 v2
| _ -> false
| MapType (k1, v1) ->
match ty2 with
| MapType (k2, v2) -> provablyEqual k1 k2 && provablyEqual v1 v2
| _ -> false
| ListType t1 ->
match ty2 with
| ListType t2 -> provablyEqual t1 t2
| _ -> false
| ArrayType t1 ->
match ty2 with
| ArrayType t2 -> provablyEqual t1 t2
| _ -> false
| Task t1 ->
match ty2 with
| Task t2 -> provablyEqual t1 t2
| _ -> false
| UnitType ->
match ty2 with
| UnitType -> true
| _ -> false
| FileInfo ->
match ty2 with
| FileInfo -> true
| _ -> false
| DirectoryInfo ->
match ty2 with
| DirectoryInfo -> true
| _ -> false
| Uri ->
match ty2 with
| Uri -> true
| _ -> false
| Stream ->
match ty2 with
| Stream -> true
| _ -> false
| Guid ->
match ty2 with
| Guid -> true
| _ -> false
| BigInt ->
match ty2 with
| BigInt -> true
| _ -> false
| DateTimeOffset ->
match ty2 with
| DateTimeOffset -> true
| _ -> false
| DateOnly ->
match ty2 with
| DateOnly -> true
| _ -> false
| _ -> false

View File

@@ -1,6 +1,9 @@
namespace WoofWare.Myriad.Plugins namespace WoofWare.Myriad.Plugins
open Fantomas.FCS.Syntax open Fantomas.FCS.Syntax
open Fantomas.FCS.Text.Range
open Fantomas.FCS.Xml
open Fantomas.FCS.SyntaxTrivia
type internal UnionCase<'Ident> = type internal UnionCase<'Ident> =
{ {
@@ -39,3 +42,34 @@ module internal SynUnionCase =
Attrs = attrs Attrs = attrs
Ident = id Ident = id
} }
let create (case : UnionCase<Ident>) : SynUnionCase =
let fields =
case.Fields
|> List.map (fun field ->
SynField.SynField (
SynAttributes.ofAttrs field.Attrs,
false,
Some field.Ident,
field.Type,
false,
PreXmlDoc.Empty,
None,
range0,
{
LeadingKeyword = None
}
)
)
SynUnionCase.SynUnionCase (
SynAttributes.ofAttrs case.Attrs,
SynIdent.SynIdent (case.Ident, None),
SynUnionCaseKind.Fields fields,
PreXmlDoc.Empty,
None,
range0,
{
BarRange = Some range0
}
)

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
@@ -18,7 +18,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Myriad.Core" Version="0.8.3" PrivateAssets="all"/> <PackageReference Include="Myriad.Core" Version="0.8.3" />
<!-- the lowest version allowed by Myriad.Core --> <!-- the lowest version allowed by Myriad.Core -->
<PackageReference Update="FSharp.Core" Version="6.0.1" PrivateAssets="all"/> <PackageReference Update="FSharp.Core" Version="6.0.1" PrivateAssets="all"/>
</ItemGroup> </ItemGroup>
@@ -26,6 +26,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="List.fs"/> <Compile Include="List.fs"/>
<Compile Include="Primitives.fs" /> <Compile Include="Primitives.fs" />
<Compile Include="SynExpr\SynAttributes.fs" />
<Compile Include="SynExpr\PreXmlDoc.fs" /> <Compile Include="SynExpr\PreXmlDoc.fs" />
<Compile Include="SynExpr\Ident.fs" /> <Compile Include="SynExpr\Ident.fs" />
<Compile Include="SynExpr\SynLongIdent.fs" /> <Compile Include="SynExpr\SynLongIdent.fs" />
@@ -46,6 +47,7 @@
<Compile Include="SynExpr\SynAttribute.fs" /> <Compile Include="SynExpr\SynAttribute.fs" />
<Compile Include="SynExpr\SynModuleDecl.fs" /> <Compile Include="SynExpr\SynModuleDecl.fs" />
<Compile Include="SynExpr\SynModuleOrNamespace.fs" /> <Compile Include="SynExpr\SynModuleOrNamespace.fs" />
<Compile Include="Measure.fs" />
<Compile Include="AstHelper.fs" /> <Compile Include="AstHelper.fs" />
<Compile Include="RemoveOptionsGenerator.fs"/> <Compile Include="RemoveOptionsGenerator.fs"/>
<Compile Include="InterfaceMockGenerator.fs"/> <Compile Include="InterfaceMockGenerator.fs"/>

View File

@@ -6,7 +6,7 @@
"pathFilters": [ "pathFilters": [
"./", "./",
":/WoofWare.Myriad.Plugins.Attributes", ":/WoofWare.Myriad.Plugins.Attributes",
"^:/WoofWare.Myriad.Plugins.Attributes/WoofWare.Myriad.Plugins.Attributes.Test", ":^/WoofWare.Myriad.Plugins.Attributes/Test",
":/global.json", ":/global.json",
":/README.md", ":/README.md",
":/Directory.Build.props" ":/Directory.Build.props"

12
flake.lock generated
View File

@@ -5,11 +5,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1701680307, "lastModified": 1710146030,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725", "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -20,11 +20,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1706367331, "lastModified": 1724395761,
"narHash": "sha256-AqgkGHRrI6h/8FWuVbnkfFmXr4Bqsr4fV23aISqj/xg=", "narHash": "sha256-zRkDV/nbrnp3Y8oCADf5ETl1sDrdmAW6/bBVJ8EbIdQ=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "160b762eda6d139ac10ae081f8f78d640dd523eb", "rev": "ae815cee91b417be55d43781eb4b73ae1ecc396c",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -17,7 +17,7 @@
dotnet-sdk = pkgs.dotnet-sdk_8; dotnet-sdk = pkgs.dotnet-sdk_8;
dotnet-runtime = pkgs.dotnetCorePackages.runtime_8_0; dotnet-runtime = pkgs.dotnetCorePackages.runtime_8_0;
version = "0.1"; version = "0.1";
dotnetTool = dllOverride: toolName: toolVersion: sha256: dotnetTool = dllOverride: toolName: toolVersion: hash:
pkgs.stdenvNoCC.mkDerivation rec { pkgs.stdenvNoCC.mkDerivation rec {
name = toolName; name = toolName;
version = toolVersion; version = toolVersion;
@@ -25,7 +25,7 @@
src = pkgs.fetchNuGet { src = pkgs.fetchNuGet {
pname = name; pname = name;
version = version; version = version;
sha256 = sha256; hash = hash;
installPhase = ''mkdir -p $out/bin && cp -r tools/net6.0/any/* $out/bin''; installPhase = ''mkdir -p $out/bin && cp -r tools/net6.0/any/* $out/bin'';
}; };
installPhase = let installPhase = let
@@ -43,8 +43,8 @@
}; };
in { in {
packages = { packages = {
fantomas = dotnetTool null "fantomas" (builtins.fromJSON (builtins.readFile ./.config/dotnet-tools.json)).tools.fantomas.version (builtins.head (builtins.filter (elem: elem.pname == "fantomas") ((import ./nix/deps.nix) {fetchNuGet = x: x;}))).sha256; fantomas = dotnetTool null "fantomas" (builtins.fromJSON (builtins.readFile ./.config/dotnet-tools.json)).tools.fantomas.version (builtins.head (builtins.filter (elem: elem.pname == "fantomas") ((import ./nix/deps.nix) {fetchNuGet = x: x;}))).hash;
fsharp-analyzers = dotnetTool "FSharp.Analyzers.Cli" "fsharp-analyzers" (builtins.fromJSON (builtins.readFile ./.config/dotnet-tools.json)).tools.fsharp-analyzers.version (builtins.head (builtins.filter (elem: elem.pname == "fsharp-analyzers") ((import ./nix/deps.nix) {fetchNuGet = x: x;}))).sha256; fsharp-analyzers = dotnetTool "FSharp.Analyzers.Cli" "fsharp-analyzers" (builtins.fromJSON (builtins.readFile ./.config/dotnet-tools.json)).tools.fsharp-analyzers.version (builtins.head (builtins.filter (elem: elem.pname == "fsharp-analyzers") ((import ./nix/deps.nix) {fetchNuGet = x: x;}))).hash;
default = pkgs.buildDotnetModule { default = pkgs.buildDotnetModule {
inherit pname version dotnet-sdk dotnet-runtime; inherit pname version dotnet-sdk dotnet-runtime;
name = "WoofWare.Myriad.Plugins"; name = "WoofWare.Myriad.Plugins";

View File

@@ -3,327 +3,327 @@
{fetchNuGet}: [ {fetchNuGet}: [
(fetchNuGet { (fetchNuGet {
pname = "ApiSurface"; pname = "ApiSurface";
version = "4.0.41"; version = "4.0.44";
sha256 = "03kfa5ngmgkik9lc58sp8s9rrh9g40hhgjnrv662ks0d0y2i9i89"; hash = "sha256-1su3UcdsyG9OoPwiMqo07rUMKhkVKlohRK4fA8mbxvI=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "fantomas"; pname = "fantomas";
version = "6.3.9"; version = "6.3.10";
sha256 = "1b34iiiff02bbzjv03zyna8xmrgs6y87zdvp5i5k58fcqpjw44sx"; hash = "sha256-2m4YevDp9CRm/Ci2hguDXd6DUMElRg3hNAne9LHntWM=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Fantomas.Core"; pname = "Fantomas.Core";
version = "6.1.1"; version = "6.1.1";
sha256 = "1h2wsiy4fzwsg9vrlpk6w7zsvx6bc4wg4x25zqc48akg04fwpi0m"; hash = "sha256-FcTLHQFvKkQY/kV08jhhy/St/+FmXpp3epp/R3zUXMA=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Fantomas.FCS"; pname = "Fantomas.FCS";
version = "6.1.1"; version = "6.1.1";
sha256 = "0733dm5zjdp8w5wwalqlv1q52pghfr04863i9wy807f4qfd7rrin"; hash = "sha256-NuZ8msPEHYA8T3EYREB28F1RcNgUU8V54eg2+UttYxw=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "FsCheck"; pname = "FsCheck";
version = "2.16.6"; version = "2.16.6";
sha256 = "176rwky6b5rk8dzldiz4068p7m9c5y9ygzbhadrs14jkl94pc56n"; hash = "sha256-1hR2SaJTkqBzU3D955MvLNVzkQHkx0Z/QzOXZfzk2Zw=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "fsharp-analyzers"; pname = "fsharp-analyzers";
version = "0.26.0"; version = "0.26.1";
sha256 = "0xgv5kvbwfdvcp6s8x7xagbbi4s3mqa4ixni6pazqvyflbgnah7b"; hash = "sha256-UqSK8PoXRJMZWKphMmWpl5klVn82EM1VczNZ1AOZ6Sw=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "FSharp.Core"; pname = "FSharp.Core";
version = "4.3.4"; version = "4.3.4";
sha256 = "1sg6i4q5nwyzh769g76f6c16876nvdpn83adqjr2y9x6xsiv5p5j"; hash = "sha256-styyo+6mJy+yxE0NZG/b1hxkAjPOnJfMgd9zWzCJ5uk=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "FSharp.Core"; pname = "FSharp.Core";
version = "6.0.1"; version = "6.0.1";
sha256 = "0qks2aadkhsffg9a6xq954ll9xacnph852avd7ljh9n2g6vj06qj"; hash = "sha256-Ehsgt3nCJijpaVuJguC1TPVEKSkJd6PSc07D2ZQSemI=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "FSharp.Core"; pname = "FSharp.Core";
version = "8.0.101"; version = "8.0.301";
sha256 = "0prgcnki6s0rlrfbarrcv50w1bbhaalsyhhw5gsnjs2is7qrjbii"; hash = "sha256-LyP+zHxXFNksSQ/ExQ9CGkQYGvld8W6JNmxMg6lTRCs=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "FsUnit"; pname = "FsUnit";
version = "6.0.0"; version = "6.0.0";
sha256 = "18q3p0z155znwj1l0qq3vq9nh9wl2i4mlfx4pmrnia4czr0xdkmb"; hash = "sha256-q87WQf6MqGhzvaQ7WkkUlCdoE94DY0CD5PaXEj64A6M=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.AspNetCore.App.Ref"; pname = "Microsoft.AspNetCore.App.Ref";
version = "6.0.26"; version = "6.0.32";
sha256 = "1d8nkz24vsm0iy2xm8y5ak2q1w1p99dxyz0y26acs6sfk2na0vm6"; hash = "sha256-1mQTxwruzhm20YdlZefrYuy7xrBs17pH4Vo0K3Tl7Fc=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.AspNetCore.App.Runtime.linux-arm64"; pname = "Microsoft.AspNetCore.App.Runtime.linux-arm64";
version = "6.0.26"; version = "6.0.32";
sha256 = "1za8lc52m4z54d68wd64c2nhzy05g3gx171k5cdlx73fbymiys9z"; hash = "sha256-cIe0F+7rgwYSmh0VuFuQsUI9iEW5hn2KCD2H8Cs/k2g=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.AspNetCore.App.Runtime.linux-x64"; pname = "Microsoft.AspNetCore.App.Runtime.linux-x64";
version = "6.0.26"; version = "6.0.32";
sha256 = "1zpbmz6z8758gwywzg0bac8kx9x39sxxc9j4a4r2jl74l9ssw4vm"; hash = "sha256-TkYv7h9NBr3I+FIaXeLU4MawJtgT2RWhs35ewGRDKx8=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.AspNetCore.App.Runtime.osx-arm64"; pname = "Microsoft.AspNetCore.App.Runtime.osx-arm64";
version = "6.0.26"; version = "6.0.32";
sha256 = "1i8ydlwjzk7j0mzvn0rpljxfp1h50zwaqalnyvfxai1fwgigzgw5"; hash = "sha256-RaC37ZQcJn7ykXJrtV7ibxh0GcalRyPKncxlqOLou+I=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.AspNetCore.App.Runtime.osx-x64"; pname = "Microsoft.AspNetCore.App.Runtime.osx-x64";
version = "6.0.26"; version = "6.0.32";
sha256 = "02src68hd3213sd1a2ms1my7i92knfmdxclvv90il9cky2zsq8kw"; hash = "sha256-vh/e46xM/HbhbBvL5eP5/DCHwCP2Bg7WoMS28nBXWV0=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.CodeCoverage"; pname = "Microsoft.CodeCoverage";
version = "17.10.0"; version = "17.10.0";
sha256 = "0s0v7jmrq85n356xv7zixvwa4z94fszjcr5vll8x4im1a2lp00f9"; hash = "sha256-yQFwqVChRtIRpbtkJr92JH2i+O7xn91NGbYgnKs8G2g=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.NET.Test.Sdk"; pname = "Microsoft.NET.Test.Sdk";
version = "17.10.0"; version = "17.10.0";
sha256 = "13g8fwl09li8fc71nk13dgkb7gahd4qhamyg2xby7am63nlchhdf"; hash = "sha256-rkHIqB2mquNXF89XBTFpUL2z5msjTBsOcyjSBCh36I0=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.NETCore.App.Host.linux-arm64"; pname = "Microsoft.NETCore.App.Host.linux-arm64";
version = "6.0.26"; version = "6.0.32";
sha256 = "19y6c6v20bgf7x7rrh4rx9y7s5fy8vp5m4j9b6gi1wp4rpb5mza4"; hash = "sha256-yDOkSHEGuGG6u+rB5u+IC3rc2tQwvbjdqmgHcl7Gkn4=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.NETCore.App.Host.linux-x64"; pname = "Microsoft.NETCore.App.Host.linux-x64";
version = "6.0.26"; version = "6.0.32";
sha256 = "0p7hhidaa3mnyiwnsijwy8578v843x8hh99255s69qwwyld6falv"; hash = "sha256-2aDGkn0QqXXHUUSAwtQQbjKl5I6S0fcQWPciqPnOiM4=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.NETCore.App.Host.osx-arm64"; pname = "Microsoft.NETCore.App.Host.osx-arm64";
version = "6.0.26"; version = "6.0.32";
sha256 = "1mq11xsv9g1vsasp6k80y7xlvwi9hrpk5dgm773fvy8538s01gfv"; hash = "sha256-n6hks4j88TRelq1O6SCeUH5GmxoSm5BWXGwnpnYJibI=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.NETCore.App.Host.osx-x64"; pname = "Microsoft.NETCore.App.Host.osx-x64";
version = "6.0.26"; version = "6.0.32";
sha256 = "1chac9b4424ihrrnlzvc7qz6j4ymfjyv4kzyazzzw19yhymdkh2s"; hash = "sha256-nBBq4RYAgimBYOn/bN6JTFvJFYaqYXMHae2pmCzRaS8=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.NETCore.App.Ref"; pname = "Microsoft.NETCore.App.Ref";
version = "6.0.26"; version = "6.0.32";
sha256 = "12gb52dhg5h9hgnyqh1zgj2w46paxv2pfh33pphl9ajhrdr7hlsb"; hash = "sha256-Fm3RUZNcro434rIu3c7unGviGeGBjXj2dGnr2mmrM2g=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.NETCore.App.Runtime.linux-arm64"; pname = "Microsoft.NETCore.App.Runtime.linux-arm64";
version = "6.0.26"; version = "6.0.32";
sha256 = "164hfrwqz5dxcbb441lridk4mzcqmarb0b7ckgvqhsvpawyjw88v"; hash = "sha256-kdj8ia/2du2oKGg4MJdO2XytpT3gQ9UOiHVCyfiX2V8=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.NETCore.App.Runtime.linux-x64"; pname = "Microsoft.NETCore.App.Runtime.linux-x64";
version = "6.0.26"; version = "6.0.32";
sha256 = "0islayddpnflviqpbq4djc4f3v9nhsa2y76k5x6il3csq5vdw2hq"; hash = "sha256-/Hti30Ba12NDJQcG8pFTg6REVUDIrxZ/hRtEZNDlgxE=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.NETCore.App.Runtime.osx-arm64"; pname = "Microsoft.NETCore.App.Runtime.osx-arm64";
version = "6.0.26"; version = "6.0.32";
sha256 = "1acn5zw1pxzmcg3c0pbf9hal36fbdh9mvbsiwra7simrk7hzqpdc"; hash = "sha256-A8MFGOMXFROH1QGUE7xzq5b5EskDyIQCQt7SLfGdSbU=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.NETCore.App.Runtime.osx-x64"; pname = "Microsoft.NETCore.App.Runtime.osx-x64";
version = "6.0.26"; version = "6.0.32";
sha256 = "00f9l9dkdz0zv5csaw8fkm6s8ckrj5n9k3ygz12daa22l3bcn6ii"; hash = "sha256-y5YB62WlMrK10bR/+nNpI8luVRlD9W9ZG3GsX7AXzUM=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.NETCore.Platforms"; pname = "Microsoft.NETCore.Platforms";
version = "1.1.0"; version = "1.1.0";
sha256 = "08vh1r12g6ykjygq5d3vq09zylgb84l63k49jc4v8faw9g93iqqm"; hash = "sha256-FeM40ktcObQJk4nMYShB61H/E8B7tIKfl9ObJ0IOcCM=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.NETCore.Platforms"; pname = "Microsoft.NETCore.Platforms";
version = "1.1.1"; version = "1.1.1";
sha256 = "164wycgng4mi9zqi2pnsf1pq6gccbqvw6ib916mqizgjmd8f44pj"; hash = "sha256-8hLiUKvy/YirCWlFwzdejD2Db3DaXhHxT7GSZx/znJg=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.NETCore.Platforms"; pname = "Microsoft.NETCore.Platforms";
version = "2.0.0"; version = "2.0.0";
sha256 = "1fk2fk2639i7nzy58m9dvpdnzql4vb8yl8vr19r2fp8lmj9w2jr0"; hash = "sha256-IEvBk6wUXSdyCnkj6tHahOJv290tVVT8tyemYcR0Yro=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.NETCore.Targets"; pname = "Microsoft.NETCore.Targets";
version = "1.1.3"; version = "1.1.3";
sha256 = "05smkcyxir59rgrmp7d6327vvrlacdgldfxhmyr1azclvga1zfsq"; hash = "sha256-WLsf1NuUfRWyr7C7Rl9jiua9jximnVvzy6nk2D2bVRc=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.TestPlatform.ObjectModel"; pname = "Microsoft.TestPlatform.ObjectModel";
version = "17.10.0"; version = "17.10.0";
sha256 = "07j69cw8r39533w4p39mnj00kahazz38760in3jfc45kmlcdb26x"; hash = "sha256-3YjVGK2zEObksBGYg8b/CqoJgLQ1jUv4GCWNjDhLRh4=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Microsoft.TestPlatform.TestHost"; pname = "Microsoft.TestPlatform.TestHost";
version = "17.10.0"; version = "17.10.0";
sha256 = "1bl471s7fx9jycr0cc8rylwf34mrvlg9qn1an6l86nisavfcyb7v"; hash = "sha256-+yzP3FY6WoOosSpYnB7duZLhOPUZMQYy8zJ1d3Q4hK4=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Myriad.Core"; pname = "Myriad.Core";
version = "0.8.3"; version = "0.8.3";
sha256 = "0s5pdckjw4x0qrbd4i3cz9iili5cppg5qnjbr7zjbbhhmxzb24xw"; hash = "sha256-vBOxfq8QriX/yUtaXN69rEQaY/psRNJWxqATLidrt2g=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Myriad.Sdk"; pname = "Myriad.Sdk";
version = "0.8.3"; version = "0.8.3";
sha256 = "0qv78c5s5m04xb8h17nnn2ig26zcyya91k2dpj745cm1cbnzvvgc"; hash = "sha256-7O397WKhskKOvE3MkJT37BvxorDWngDR6gTUogtDZ2M=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Nerdbank.GitVersioning"; pname = "Nerdbank.GitVersioning";
version = "3.6.139"; version = "3.6.141";
sha256 = "0npcryhq3r0c2zi940jk39h13mzc4hyg7z8gm6jdmxi1aqv1vh8c"; hash = "sha256-i1pBJ12vlPmde6qSQK4PG2QLSpjaUCoY+odTi24R5XI=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "NETStandard.Library"; pname = "NETStandard.Library";
version = "2.0.3"; version = "2.0.3";
sha256 = "1fn9fxppfcg4jgypp2pmrpr6awl3qz1xmnri0cygpkwvyx27df1y"; hash = "sha256-Prh2RPebz/s8AzHb2sPHg3Jl8s31inv9k+Qxd293ybo=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Newtonsoft.Json"; pname = "Newtonsoft.Json";
version = "13.0.1"; version = "13.0.1";
sha256 = "0fijg0w6iwap8gvzyjnndds0q4b8anwxxvik7y8vgq97dram4srb"; hash = "sha256-K2tSVW4n4beRPzPu3rlVaBEMdGvWSv/3Q1fxaDh4Mjo=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "Newtonsoft.Json"; pname = "Newtonsoft.Json";
version = "13.0.3"; version = "13.0.3";
sha256 = "0xrwysmrn4midrjal8g2hr1bbg38iyisl0svamb11arqws4w2bw7"; hash = "sha256-hy/BieY4qxBWVVsDqqOPaLy1QobiIapkbrESm6v2PHc=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "NuGet.Common"; pname = "NuGet.Common";
version = "6.10.0"; version = "6.10.1";
sha256 = "0nizrnilmlcqbm945293h8q3wfqfchb4xi8g50x4kjn0rbpd1kbh"; hash = "sha256-2gZe1zwSaZsr0nipaMBJixLEVOvR7vp75kwecSSYyfw=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "NuGet.Configuration"; pname = "NuGet.Configuration";
version = "6.10.0"; version = "6.10.1";
sha256 = "1aqaknaawnqx4mnvx9qw73wvj48jjzv0d78dzwl7m9zjlrl9myhz"; hash = "sha256-RmjvlbtJssxuWEiOcVJLtUVT0nPn7IUPb878NmJbwmM=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "NuGet.Frameworks"; pname = "NuGet.Frameworks";
version = "6.10.0"; version = "6.10.1";
sha256 = "0hrd8y31zx9a0wps49czw0qgbrakb49zn3abfgylc9xrq990zkqk"; hash = "sha256-AdfpuVDDy9zYAGgcMZoTf/fkFCJJVrxRFhsv6AI4Dd0=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "NuGet.Packaging"; pname = "NuGet.Packaging";
version = "6.10.0"; version = "6.10.1";
sha256 = "18s53cvrf51lihmaqqdf48p2qi6ky1l48jv0hvbp76cxwdg7rba4"; hash = "sha256-ogsVjOao+LKUOMhGir1flDuMPjOeR2OpkNGHtr/riH4=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "NuGet.Protocol"; pname = "NuGet.Protocol";
version = "6.10.0"; version = "6.10.1";
sha256 = "0hmv4q0ks9i34mfgpb13l01la9v3jjllfh1qd3aqv105xrqrdxac"; hash = "sha256-UeS/10z1EqswbeB0c7QgBIVOp0VGlN5ZDQqTY2/AhX8=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "NuGet.Versioning"; pname = "NuGet.Versioning";
version = "6.10.0"; version = "6.10.1";
sha256 = "1x19njx4x0sw9fz8y5fibi15xfsrw5avir0cx0599yd7p3ykik5g"; hash = "sha256-jOh27AORk0TIhVePDVAgVhh6FuUo2v3oh/Xapcw7UVI=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "NUnit"; pname = "NUnit";
version = "4.1.0"; version = "4.1.0";
sha256 = "0fj6xwgqaxq3mrai86bklclfmjkzf038mrslwfqf4ignaz9f7g5j"; hash = "sha256-srzj0lf2ReKw41TnigZwf8rqKKNzGRRVrgN3hR/vRjo=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "NUnit3TestAdapter"; pname = "NUnit3TestAdapter";
version = "4.5.0"; version = "4.6.0";
sha256 = "1srx1629s0k1kmf02nmz251q07vj6pv58mdafcr5dr0bbn1fh78i"; hash = "sha256-9Yav2fYhC4w0OgsyUwU4/5rDy4FVDTpKnWHuwl/uKJQ=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "RestEase"; pname = "RestEase";
version = "1.6.4"; version = "1.6.4";
sha256 = "1mvi3nbrr450g3fgd1y4wg3bwl9k1agyjfd9wdkqk12714bsln8l"; hash = "sha256-FFmqFwlHhIln46k56Z8KM1G+xuPEh/bceKCQnJcdcdc=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "runtime.any.System.Runtime"; pname = "runtime.any.System.Runtime";
version = "4.3.0"; version = "4.3.0";
sha256 = "1cqh1sv3h5j7ixyb7axxbdkqx6cxy00p4np4j91kpm492rf4s25b"; hash = "sha256-qwhNXBaJ1DtDkuRacgHwnZmOZ1u9q7N8j0cWOLYOELM=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "runtime.native.System"; pname = "runtime.native.System";
version = "4.3.0"; version = "4.3.0";
sha256 = "15hgf6zaq9b8br2wi1i3x0zvmk410nlmsmva9p0bbg73v6hml5k4"; hash = "sha256-ZBZaodnjvLXATWpXXakFgcy6P+gjhshFXmglrL5xD5Y=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "runtime.unix.System.Private.Uri"; pname = "runtime.unix.System.Private.Uri";
version = "4.3.0"; version = "4.3.0";
sha256 = "1jx02q6kiwlvfksq1q9qr17fj78y5v6mwsszav4qcz9z25d5g6vk"; hash = "sha256-c5tXWhE/fYbJVl9rXs0uHh3pTsg44YD1dJvyOA0WoMs=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.Diagnostics.DiagnosticSource"; pname = "System.Diagnostics.DiagnosticSource";
version = "7.0.0"; version = "7.0.0";
sha256 = "1jxhvsh5mzdf0sgb4dfmbys1b12ylyr5pcfyj1map354fiq3qsgm"; hash = "sha256-9Wk8cHSkjKtqkN6xW7KnXoQVtF/VNbKeBq79WqDesMs=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.Formats.Asn1"; pname = "System.Formats.Asn1";
version = "6.0.0"; version = "6.0.0";
sha256 = "1vvr7hs4qzjqb37r0w1mxq7xql2b17la63jwvmgv65s1hj00g8r9"; hash = "sha256-KaMHgIRBF7Nf3VwOo+gJS1DcD+41cJDPWFh+TDQ8ee8=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.IO.Abstractions"; pname = "System.IO.Abstractions";
version = "4.2.13"; version = "4.2.13";
sha256 = "0s784iphsmj4vhkrzq9q3w39vsn76w44zclx3hsygsw458zbyh4y"; hash = "sha256-nkC/PiqE6+c1HJ2yTwg3x+qdBh844Z8n3ERWDW8k6Gg=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.IO.FileSystem.AccessControl"; pname = "System.IO.FileSystem.AccessControl";
version = "4.5.0"; version = "4.5.0";
sha256 = "1gq4s8w7ds1sp8f9wqzf8nrzal40q5cd2w4pkf4fscrl2ih3hkkj"; hash = "sha256-ck44YBQ0M+2Im5dw0VjBgFD1s0XuY54cujrodjjSBL8=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.Memory"; pname = "System.Memory";
version = "4.5.5"; version = "4.5.5";
sha256 = "08jsfwimcarfzrhlyvjjid61j02irx6xsklf32rv57x2aaikvx0h"; hash = "sha256-EPQ9o1Kin7KzGI5O3U3PUQAZTItSbk9h/i4rViN3WiI=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.Private.Uri"; pname = "System.Private.Uri";
version = "4.3.0"; version = "4.3.0";
sha256 = "04r1lkdnsznin0fj4ya1zikxiqr0h6r6a1ww2dsm60gqhdrf0mvx"; hash = "sha256-fVfgcoP4AVN1E5wHZbKBIOPYZ/xBeSIdsNF+bdukIRM=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.Reflection.Metadata"; pname = "System.Reflection.Metadata";
version = "1.6.0"; version = "1.6.0";
sha256 = "1wdbavrrkajy7qbdblpbpbalbdl48q3h34cchz24gvdgyrlf15r4"; hash = "sha256-JJfgaPav7UfEh4yRAQdGhLZF1brr0tUWPl6qmfNWq/E=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.Runtime"; pname = "System.Runtime";
version = "4.3.1"; version = "4.3.1";
sha256 = "03ch4d2acf6q037a4njxpll2kkx3dwzlg07yxr4z5m6j1kqgmm27"; hash = "sha256-R9T68AzS1PJJ7v6ARz9vo88pKL1dWqLOANg4pkQjkA0=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.Runtime.CompilerServices.Unsafe"; pname = "System.Runtime.CompilerServices.Unsafe";
version = "6.0.0"; version = "6.0.0";
sha256 = "0qm741kh4rh57wky16sq4m0v05fxmkjjr87krycf5vp9f0zbahbc"; hash = "sha256-bEG1PnDp7uKYz/OgLOWs3RWwQSVYm+AnPwVmAmcgp2I=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.Security.AccessControl"; pname = "System.Security.AccessControl";
version = "4.5.0"; version = "4.5.0";
sha256 = "1wvwanz33fzzbnd2jalar0p0z3x0ba53vzx1kazlskp7pwyhlnq0"; hash = "sha256-AFsKPb/nTk2/mqH/PYpaoI8PLsiKKimaXf+7Mb5VfPM=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.Security.Cryptography.Pkcs"; pname = "System.Security.Cryptography.Pkcs";
version = "6.0.4"; version = "6.0.4";
sha256 = "0hh5h38pnxmlrnvs72f2hzzpz4b2caiiv6xf8y7fzdg84r3imvfr"; hash = "sha256-2e0aRybote+OR66bHaNiYpF//4fCiaO3zbR2e9GABUI=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.Security.Cryptography.ProtectedData"; pname = "System.Security.Cryptography.ProtectedData";
version = "4.4.0"; version = "4.4.0";
sha256 = "1q8ljvqhasyynp94a1d7jknk946m20lkwy2c3wa8zw2pc517fbj6"; hash = "sha256-Ri53QmFX8I8UH0x4PikQ1ZA07ZSnBUXStd5rBfGWFOE=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.Security.Principal.Windows"; pname = "System.Security.Principal.Windows";
version = "4.5.0"; version = "4.5.0";
sha256 = "0rmj89wsl5yzwh0kqjgx45vzf694v9p92r4x4q6yxldk1cv1hi86"; hash = "sha256-BkUYNguz0e4NJp1kkW7aJBn3dyH9STwB5N8XqnlCsmY=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.Text.Encodings.Web"; pname = "System.Text.Encodings.Web";
version = "7.0.0"; version = "7.0.0";
sha256 = "1151hbyrcf8kyg1jz8k9awpbic98lwz9x129rg7zk1wrs6vjlpxl"; hash = "sha256-tF8qt9GZh/nPy0mEnj6nKLG4Lldpoi/D8xM5lv2CoYQ=";
}) })
(fetchNuGet { (fetchNuGet {
pname = "System.Text.Json"; pname = "System.Text.Json";
version = "7.0.3"; version = "7.0.3";
sha256 = "0zjrnc9lshagm6kdb9bdh45dmlnkpwcpyssa896sda93ngbmj8k9"; hash = "sha256-aSJZ17MjqaZNQkprfxm/09LaCoFtpdWmqU9BTROzWX4=";
}) })
] ]