├── .gitignore
├── CHANGES.md
├── assets
├── icon.png
└── Destructurama.snk
├── .github
├── codecov.yml
├── dependabot.yml
├── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
├── labeler.yml
└── workflows
│ ├── label.yml
│ ├── stale.yml
│ ├── publish-preview.yml
│ ├── publish-release.yml
│ └── test.yml
├── src
├── Destructurama.FSharp
│ ├── packages.config
│ ├── Destructurama.FSharp.fsproj
│ ├── Destructurama.FSharp.nuspec
│ └── DestructuramaFSharp.fs
├── Samples
│ ├── Samples.fsproj
│ └── Program.fs
├── Destructurama.FSharp.Tests
│ ├── Destructurama.FSharp.Tests.fsproj
│ └── Tests.fs
├── destructurama-fsharp.slnx
└── Directory.Build.props
├── README.md
├── LICENSE
└── .editorconfig
/.gitignore:
--------------------------------------------------------------------------------
1 | .vs/
2 | obj/
3 | bin/
4 |
--------------------------------------------------------------------------------
/CHANGES.md:
--------------------------------------------------------------------------------
1 | 1.0
2 | * Migrated from Serilog.Extras.FSharp at serilog/serilog
3 |
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/destructurama/fsharp/HEAD/assets/icon.png
--------------------------------------------------------------------------------
/.github/codecov.yml:
--------------------------------------------------------------------------------
1 | # https://docs.codecov.com/docs/codecov-yaml
2 | comment:
3 | behavior: new
4 |
--------------------------------------------------------------------------------
/assets/Destructurama.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/destructurama/fsharp/HEAD/assets/Destructurama.snk
--------------------------------------------------------------------------------
/src/Destructurama.FSharp/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 |
4 | - package-ecosystem: "nuget"
5 | directory: "src"
6 | schedule:
7 | interval: "daily"
8 |
9 | - package-ecosystem: "github-actions"
10 | directory: "/"
11 | schedule:
12 | interval: "daily"
13 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: sungam3r
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is.
12 |
13 | **Describe the solution you'd like**
14 | This is optional description of what you want to happen.
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: sungam3r
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **Expected behavior**
14 | A clear and concise description of what you expected to happen.
15 |
16 | **Screenshots and any additional context**
17 | If applicable, add screenshots or any other context here to help explain your problem.
18 |
--------------------------------------------------------------------------------
/.github/labeler.yml:
--------------------------------------------------------------------------------
1 | tests:
2 | - changed-files:
3 | - any-glob-to-any-file:
4 | - src/Destructurama.FSharp.Tests/**/*
5 |
6 | CI:
7 | - changed-files:
8 | - any-glob-to-any-file:
9 | - .github/workflows/**/*
10 | - .github/dependabot.yml
11 | - .github/codecov.yml
12 | - .github/labeler.yml
13 |
14 | code style:
15 | - changed-files:
16 | - any-glob-to-any-file:
17 | - .editorconfig
18 |
19 | documentation:
20 | - changed-files:
21 | - any-glob-to-any-file:
22 | - README.md
23 |
--------------------------------------------------------------------------------
/src/Samples/Samples.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net10.0
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/.github/workflows/label.yml:
--------------------------------------------------------------------------------
1 | # This workflow will triage pull requests and apply a label based on the
2 | # paths that are modified in the pull request.
3 | #
4 | # To use this workflow, you will need to set up a .github/labeler.yml
5 | # file with configuration. For more information, see:
6 | # https://github.com/actions/labeler/blob/master/README.md
7 |
8 | name: Labeler
9 | on:
10 | pull_request_target:
11 | types:
12 | - opened # when PR is opened
13 |
14 | jobs:
15 | label:
16 | runs-on: ubuntu-latest
17 | steps:
18 | - uses: actions/labeler@v6
19 | with:
20 | repo-token: "${{ secrets.GITHUB_TOKEN }}"
21 | continue-on-error: true
22 |
--------------------------------------------------------------------------------
/src/Destructurama.FSharp/Destructurama.FSharp.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | F# Destructuring extensions for Serilog
6 | Native support for destructuring F# types when logging to Serilog.
7 | $(WarningsNotAsErrors);FS3261
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | name: Mark stale issues and pull requests
2 |
3 | on:
4 | schedule:
5 | - cron: "0 0 * * *"
6 |
7 | jobs:
8 | stale:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/stale@v10
12 | with:
13 | repo-token: ${{ secrets.GITHUB_TOKEN }}
14 | stale-issue-message: 'This issue was marked as stale since it has not been active for a long time'
15 | stale-pr-message: 'This pull request was marked as stale since it has not been active for a long time'
16 | stale-issue-label: 'stale'
17 | stale-pr-label: 'stale'
18 | days-before-stale: 30
19 | days-before-close: 60
20 | exempt-issue-label: 'not so stale'
21 | exempt-pr-label: 'not so stale'
22 | operations-per-run: 30
23 |
--------------------------------------------------------------------------------
/src/Destructurama.FSharp.Tests/Destructurama.FSharp.Tests.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net10.0
5 | $(WarningsNotAsErrors);FS3261
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/Destructurama.FSharp/Destructurama.FSharp.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Destructurama.FSharp
5 | $version$
6 | Destructurama Contributors, Serilog Contributors
7 | Native support for destructuring F# types when logging to Serilog.
8 | en-US
9 | http://serilog.net
10 | http://www.apache.org/licenses/LICENSE-2.0
11 | http://destructurama.github.io/pages/images/destructurama.png
12 | serilog fsharp
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/Samples/Program.fs:
--------------------------------------------------------------------------------
1 | // Learn more about F# at http://fsharp.org
2 |
3 | open Serilog
4 |
5 | let goodLogger =
6 | LoggerConfiguration()
7 | .Destructure.FSharpTypes()
8 | .WriteTo.Console()
9 | .CreateLogger()
10 |
11 | let badLogger =
12 | LoggerConfiguration()
13 | .WriteTo.Console()
14 | .CreateLogger()
15 |
16 | type Union = A | B of bool | C of quantity: int * label: string
17 |
18 | type MyRecord =
19 | { FieldA : int
20 | OtherField: bool
21 | AnotherOne: Union }
22 |
23 | []
24 | let main argv =
25 |
26 | let union = C (10, "hi")
27 |
28 | badLogger.Information("Printing a {@union} with poor destructuring", union)
29 | goodLogger.Information("Printing a {@union} with better destructuring", union)
30 |
31 | let record =
32 | { FieldA = 10
33 | OtherField = true
34 | AnotherOne = union }
35 |
36 | badLogger.Information("Printing a {@record} with poor destructuring", record)
37 | goodLogger.Information("Printing a {@record} with better destructuring", record)
38 |
39 | let tuple = 1, "hi"
40 |
41 | badLogger.Information("Printing a {@tuple} with poor destructuring", tuple)
42 | goodLogger.Information("Printing a {@tuple} with better destructuring", tuple)
43 |
44 | 0 // return an integer exit code
45 |
--------------------------------------------------------------------------------
/src/destructurama-fsharp.slnx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/Destructurama.FSharp.Tests/Tests.fs:
--------------------------------------------------------------------------------
1 | module Tests
2 |
3 | open Xunit
4 | open Destructurama.FSharp
5 |
6 | type Decision = Yes | No | MaybeSo
7 |
8 | type MyRecord =
9 | { FieldA : int
10 | OtherField: bool
11 | AnotherOne: Decision }
12 |
13 | // dummy converter that always returns true
14 | let alwaysTrueConverter =
15 | { new Serilog.Core.ILogEventPropertyValueFactory with
16 | member __.CreatePropertyValue(data, shouldDestructure) = Serilog.Events.ScalarValue(true) :> _ }
17 |
18 | let policy =
19 | FSharpTypesDestructuringPolicy() :> Serilog.Core.IDestructuringPolicy
20 |
21 | let inline doDestructuring data =
22 | match policy.TryDestructure(data, alwaysTrueConverter) with
23 | | true, property ->
24 | printfn "rendered data \n%A as \n%s" data (property.ToString())
25 | | false, _ ->
26 | failwithf "was unable to destructure an object of type %s" (data.GetType().FullName)
27 |
28 | []
29 | let ``can destructure tuple`` () = doDestructuring (1,2)
30 |
31 | []
32 | let ``can destructure struct tuple`` () = doDestructuring (struct (1,2))
33 |
34 | []
35 | let ``can destructure union`` () = doDestructuring (Some "thing")
36 |
37 | []
38 | let ``can destructure struct union`` () = doDestructuring (ValueSome "thing")
39 |
40 | []
41 | let ``can destructure record`` () = doDestructuring { FieldA = 10
42 | OtherField = true
43 | AnotherOne = MaybeSo }
--------------------------------------------------------------------------------
/.github/workflows/publish-preview.yml:
--------------------------------------------------------------------------------
1 | name: Publish preview to GitHub registry
2 |
3 | # ==== NOTE: do not rename this yml file or the $GITHUB_RUN_NUMBER will be reset ====
4 |
5 | on:
6 | push:
7 | branches:
8 | - master
9 | paths:
10 | - src/**
11 | - .github/workflows/**
12 |
13 | env:
14 | DOTNET_NOLOGO: true
15 | DOTNET_CLI_TELEMETRY_OPTOUT: true
16 |
17 | jobs:
18 | pack:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - uses: actions/checkout@v6
22 | with:
23 | fetch-depth: 0
24 | - name: Setup .NET SDK
25 | uses: actions/setup-dotnet@v5
26 | with:
27 | dotnet-version: 10.0.x
28 | source-url: https://nuget.pkg.github.com/destructurama/index.json
29 | env:
30 | NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
31 | - name: Install dependencies
32 | working-directory: src
33 | run: dotnet restore
34 | - name: Build solution [Release]
35 | working-directory: src
36 | run: dotnet build --no-restore -c Release
37 | - name: Pack solution [Release]
38 | working-directory: src
39 | run: dotnet pack --no-build -c Release -o out
40 | - name: Upload artifacts
41 | uses: actions/upload-artifact@v6
42 | with:
43 | name: Nuget packages
44 | path: |
45 | src/out/*
46 | - name: Publish Nuget packages to GitHub registry
47 | working-directory: src
48 | run: dotnet nuget push "out/*" -k ${{secrets.GITHUB_TOKEN}}
49 |
--------------------------------------------------------------------------------
/.github/workflows/publish-release.yml:
--------------------------------------------------------------------------------
1 | name: Publish release to Nuget registry
2 |
3 | on:
4 | release:
5 | types:
6 | - published
7 |
8 | env:
9 | DOTNET_NOLOGO: true
10 | DOTNET_CLI_TELEMETRY_OPTOUT: true
11 |
12 | jobs:
13 | publish:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v6
17 | with:
18 | fetch-depth: 0
19 | - name: Setup .NET SDK
20 | uses: actions/setup-dotnet@v5
21 | with:
22 | dotnet-version: 10.0.x
23 | source-url: https://api.nuget.org/v3/index.json
24 | env:
25 | NUGET_AUTH_TOKEN: ${{secrets.NUGET_AUTH_TOKEN}}
26 | - name: Install dependencies
27 | working-directory: src
28 | run: dotnet restore
29 | - name: Build solution [Release]
30 | working-directory: src
31 | run: dotnet build --no-restore -c Release
32 | - name: Pack solution [Release]
33 | working-directory: src
34 | run: dotnet pack --no-build -c Release -o out
35 | - name: Upload artifacts
36 | uses: actions/upload-artifact@v6
37 | with:
38 | name: Nuget packages
39 | path: |
40 | src/out/*
41 | - name: Publish Nuget packages to Nuget registry
42 | working-directory: src
43 | run: dotnet nuget push "out/*" -k ${{secrets.NUGET_AUTH_TOKEN}}
44 | - name: Upload Nuget packages as release artifacts
45 | uses: actions/github-script@v8
46 | with:
47 | github-token: ${{secrets.GITHUB_TOKEN}}
48 | script: |
49 | console.log('environment', process.versions);
50 | const fs = require('fs').promises;
51 | const { repo: { owner, repo }, sha } = context;
52 |
53 | for (let file of await fs.readdir('src/out')) {
54 | console.log('uploading', file);
55 |
56 | await github.rest.repos.uploadReleaseAsset({
57 | owner,
58 | repo,
59 | release_id: ${{ github.event.release.id }},
60 | name: file,
61 | data: await fs.readFile(`src/out/${file}`)
62 | });
63 | }
64 |
--------------------------------------------------------------------------------
/src/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 | true
6 |
7 | latest
8 | true
9 | true
10 | true
11 | Destructurama Contributors, Serilog Contributors
12 | $([System.DateTime]::Now.ToString(yyyy))
13 | Copyright © Serilog Contributors 2019-$(CurrentYear)
14 | Apache-2.0
15 | false
16 | icon.png
17 | embedded
18 | true
19 | true
20 |
21 | True
22 | serilog;fsharp
23 | enable
24 | README.md
25 | true
26 | enable
27 | true
28 | ../../assets/Destructurama.snk
29 |
30 | ../../../../../../assets/Destructurama.snk
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Run unit tests
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - master
7 | paths:
8 | - src/**
9 | - .github/workflows/**
10 | # Upload code coverage results when PRs are merged
11 | push:
12 | branches:
13 | - master
14 | paths:
15 | - src/**
16 | - .github/workflows/**
17 |
18 | env:
19 | DOTNET_NOLOGO: true
20 | DOTNET_CLI_TELEMETRY_OPTOUT: true
21 |
22 | jobs:
23 | test:
24 | strategy:
25 | matrix:
26 | os: [ubuntu-latest, windows-latest]
27 | name: ${{ matrix.os }}
28 | runs-on: ${{ matrix.os }}
29 | steps:
30 | - uses: actions/checkout@v6
31 | with:
32 | fetch-depth: 0
33 | - name: Setup .NET SDKs
34 | uses: actions/setup-dotnet@v5
35 | with:
36 | dotnet-version: 10.0.x
37 | source-url: https://nuget.pkg.github.com/destructurama/index.json
38 | env:
39 | NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
40 | - name: Install dependencies
41 | working-directory: src
42 | run: dotnet restore
43 | - name: Check formatting
44 | if: ${{ startsWith(matrix.os, 'ubuntu') }}
45 | working-directory: src
46 | run: |
47 | dotnet format --no-restore --verify-no-changes --severity warn || (echo "Run 'dotnet format' to fix issues" && exit 1)
48 | - name: Build solution [Release]
49 | working-directory: src
50 | run: dotnet build --no-restore -c Release
51 | - name: Build solution [Debug]
52 | working-directory: src
53 | run: dotnet build --no-restore -c Debug
54 | - name: Test solution [Debug]
55 | working-directory: src
56 | run: dotnet test --no-build -p:CollectCoverage=true -p:CoverletOutputFormat=opencover -p:CoverletOutput=../.coverage/
57 | - name: Upload coverage to codecov
58 | if: ${{ startsWith(matrix.os, 'ubuntu') }}
59 | uses: codecov/codecov-action@v5
60 | with:
61 | token: ${{ secrets.CODECOV_TOKEN }}
62 | files: src/.coverage/*.opencover.xml
63 |
64 | buildcheck:
65 | needs:
66 | - test
67 | runs-on: ubuntu-latest
68 | if: always()
69 | steps:
70 | - name: Pass build check
71 | if: ${{ needs.test.result == 'success' }}
72 | run: exit 0
73 | - name: Fail build check
74 | if: ${{ needs.test.result != 'success' }}
75 | run: exit 1
76 |
--------------------------------------------------------------------------------
/src/Destructurama.FSharp/DestructuramaFSharp.fs:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Destructurama Contributors, Serilog Contributors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | namespace Destructurama.FSharp
16 |
17 | open Microsoft.FSharp.Reflection
18 | open Serilog.Core
19 | open Serilog.Events
20 |
21 | ///
22 | /// A destructuring policy for Serilog loggers that understands how to unwrap
23 | /// and display common F# data types, such as Tuples and Unions.
24 | ///
25 | type public FSharpTypesDestructuringPolicy() =
26 | interface Serilog.Core.IDestructuringPolicy with
27 | member __.TryDestructure(value,
28 | propertyValueFactory : ILogEventPropertyValueFactory,
29 | result: byref) =
30 | let cpv obj = propertyValueFactory.CreatePropertyValue(obj, true)
31 | let lep (n:System.Reflection.PropertyInfo) (v:obj) = LogEventProperty(n.Name, cpv v)
32 | match value.GetType() with
33 | | t when FSharpType.IsTuple t ->
34 | result <- SequenceValue(value |> FSharpValue.GetTupleFields |> Seq.map cpv)
35 | true
36 | // TODO: support for Maps and Sets? Why do Lists here when surely some IEnumerable-binder can handle them?
37 | | t when t.IsConstructedGenericType && t.GetGenericTypeDefinition() = typedefof> ->
38 | let objEnumerable = value :?> System.Collections.IEnumerable |> Seq.cast
39 | result <- SequenceValue(objEnumerable |> Seq.map cpv)
40 | true
41 | | t when FSharpType.IsUnion t ->
42 | let case, fields = FSharpValue.GetUnionFields(value, t)
43 | let properties = (case.GetFields(), fields) ||> Seq.map2 lep
44 | result <- StructureValue(properties, case.Name)
45 | true
46 | | t when FSharpType.IsRecord t ->
47 | let fields = FSharpValue.GetRecordFields value
48 | let fieldNames = FSharpType.GetRecordFields t
49 | let properties = (fieldNames, fields) ||> Seq.map2 lep
50 | result <- StructureValue(properties, t.Name)
51 | true
52 | | _ -> false
53 |
54 | namespace Serilog
55 |
56 | open Serilog.Configuration
57 | open Destructurama.FSharp
58 |
59 | []
60 | module public LoggerDestructuringConfigurationExtensions =
61 | type public LoggerDestructuringConfiguration with
62 | member public this.FSharpTypes() =
63 | this.With()
64 |
65 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Destructurama.FSharp
2 |
3 | # ATTENTION! Looking for maintainers
4 |
5 | See https://github.com/destructurama/fsharp/issues/34
6 |
7 | 
8 |
9 | [](https://codecov.io/gh/destructurama/fsharp)
10 | [](https://www.nuget.org/packages/Destructurama.FSharp)
11 | [](https://www.nuget.org/packages/Destructurama.FSharp)
12 |
13 | [](https://github.com/destructurama/fsharp/releases)
14 | [](https://github.com/destructurama/fsharp/commits/master)
15 | 
16 |
17 | [](https://github.com/destructurama/fsharp/graphs/contributors)
18 | 
19 | 
20 | 
21 |
22 | [](https://github.com/destructurama/fsharp/actions/workflows/test.yml)
23 | [](https://github.com/destructurama/fsharp/actions/workflows/publish-preview.yml)
24 | [](https://github.com/destructurama/fsharp/actions/workflows/publish-release.yml)
25 |
26 | Native support for destructuring F# types when logging to [Serilog](https://serilog.net).
27 |
28 | # Installation
29 |
30 | Install from NuGet:
31 |
32 | ```
33 | dotnet add package Destructurama.FSharp
34 | ```
35 |
36 | # Usage
37 |
38 | Add `Destructure.FSharpTypes()` to your logger configuration:
39 |
40 | ```fsharp
41 | open Serilog
42 |
43 | []
44 | let main argv =
45 |
46 | Log.Logger <- LoggerConfiguration()
47 | .Destructure.FSharpTypes()
48 | .WriteTo.Console()
49 | .CreateLogger()
50 |
51 | Log.Information("Drawing a {@Shape}", Circle 5.)
52 |
53 | 0
54 | ```
55 |
56 | Discriminated unions like:
57 |
58 | ```fsharp
59 | type Shape =
60 | | Circle of Radius : double
61 | | Rectangle of Width : double * Height : double
62 | | Arc // ...
63 | let shape = Circle 5.
64 | ```
65 |
66 | When logged with Serilog:
67 |
68 | ```fsharp
69 | Log.Information("Drawing a {@Shape}", shape)
70 | ```
71 |
72 | Are printed nicely like:
73 |
74 | ```
75 | 2015-01-14 16:58:31 [Information] Drawing a Circle { Radius: 5 }
76 | ```
77 |
78 | Depending on the log storage you use you will be able to query on the tag as well
79 | as the fields (like Radius) from the union.
80 |
81 | More samples can be seen by running the project in the `Samples` folder using
82 | `dotnet run`. Doing so will destructure a union, record, and a tuple with and
83 | without this package to highlight the difference:
84 |
85 | ```
86 | ➜ samples git:(records) ✗ dotnet run
87 | [13:35:19 INF] Printing a {"quantity": 10, "label": "hi", "Tag": 2, "IsA": false, "IsB": false, "IsC": true, "$type": "C"} with poor destructuring
88 | [13:35:19 INF] Printing a {"quantity": 10, "label": "hi", "$type": "C"} with better destructuring
89 |
90 | [13:35:19 INF] Printing a {"FieldA": 10, "OtherField": true, "AnotherOne": {"quantity": 10, "label": "hi", "Tag": 2, "IsA": false, "IsB": false, "IsC": true, "$type": "C"}, "$type": "MyRecord"} with poor destructuring
91 | [13:35:19 INF] Printing a {"FieldA": 10, "OtherField": true, "AnotherOne": {"quantity": 10, "label": "hi", "$type": "C"}, "$type": "MyRecord"} with better destructuring
92 |
93 | [13:35:19 INF] Printing a {"Item1": 1, "Item2": "hi", "$type": "Tuple`2"} with poor destructuring
94 | [13:35:19 INF] Printing a [1, "hi"] with better destructuring
95 | ```
96 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # Create portable, custom editor settings with EditorConfig
4 | # https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options
5 |
6 | # .NET coding convention settings for EditorConfig
7 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2019
8 |
9 | # Language conventions
10 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019
11 |
12 | # Formatting conventions
13 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-formatting-conventions?view=vs-2019
14 |
15 | # .NET naming conventions for EditorConfig
16 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-naming-conventions?view=vs-2019
17 |
18 | # Top-most EditorConfig file
19 | root = true
20 |
21 | # Editor default newlines with a newline ending every file
22 | [*]
23 | insert_final_newline = true
24 | charset = utf-8
25 | indent_style = space
26 | indent_size = 2
27 | trim_trailing_whitespace = true
28 |
29 | [*.json]
30 | insert_final_newline = false
31 |
32 | [*.cs]
33 | indent_size = 4
34 |
35 | # Do not insert newline for ApiApprovalTests
36 | [*.txt]
37 | insert_final_newline = false
38 |
39 | # Code files
40 | [*.{cs,vb}]
41 |
42 | # .NET code style settings - "This." and "Me." qualifiers
43 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#this-and-me
44 | dotnet_style_qualification_for_field = false:warning
45 | dotnet_style_qualification_for_property = false:warning
46 | dotnet_style_qualification_for_method = false:warning
47 | dotnet_style_qualification_for_event = false:warning
48 |
49 | # .NET code style settings - Language keywords instead of framework type names for type references
50 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#language-keywords
51 | dotnet_style_predefined_type_for_locals_parameters_members = true:error
52 | dotnet_style_predefined_type_for_member_access = true:error
53 |
54 | # .NET code style settings - Modifier preferences
55 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#normalize-modifiers
56 | dotnet_style_require_accessibility_modifiers = for_non_interface_members:warning
57 | csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:warning
58 | dotnet_style_readonly_field = true:warning
59 |
60 | # .NET code style settings - Parentheses preferences
61 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#parentheses-preferences
62 | dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:suggestion
63 | dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:suggestion
64 | dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:suggestion
65 | dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
66 |
67 | # .NET code style settings - Expression-level preferences
68 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#expression-level-preferences
69 | dotnet_style_object_initializer = true:error
70 | dotnet_style_collection_initializer = true:error
71 | dotnet_style_explicit_tuple_names = true:warning
72 | dotnet_style_prefer_inferred_tuple_names = true:suggestion
73 | dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
74 | dotnet_style_prefer_auto_properties = true:warning
75 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
76 | dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
77 | dotnet_style_prefer_conditional_expression_over_return = true:suggestion
78 | dotnet_style_prefer_compound_assignment = true:warning
79 |
80 | # .NET code style settings - Null-checking preferences
81 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#null-checking-preferences
82 | dotnet_style_coalesce_expression = true:warning
83 | dotnet_style_null_propagation = true:error
84 |
85 | # .NET code quality settings - Parameter preferences
86 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#parameter-preferences
87 | dotnet_code_quality_unused_parameters = all:warning
88 |
89 | # C# code style settings - Implicit and explicit types
90 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#implicit-and-explicit-types
91 | csharp_style_var_for_built_in_types = false:suggestion
92 | csharp_style_var_when_type_is_apparent = true:warning
93 | csharp_style_var_elsewhere = true:suggestion
94 |
95 | # C# code style settings - Expression-bodied members
96 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#expression-bodied-members
97 | csharp_style_expression_bodied_methods = when_on_single_line:suggestion
98 | csharp_style_expression_bodied_constructors = false:warning
99 | csharp_style_expression_bodied_operators = when_on_single_line:warning
100 | csharp_style_expression_bodied_properties = when_on_single_line:warning
101 | csharp_style_expression_bodied_indexers = when_on_single_line:warning
102 | csharp_style_expression_bodied_accessors = when_on_single_line:warning
103 | csharp_style_expression_bodied_lambdas = when_on_single_line:warning
104 | csharp_style_expression_bodied_local_functions = when_on_single_line:warning
105 |
106 | # C# code style settings - Pattern matching
107 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#pattern-matching
108 | csharp_style_pattern_matching_over_is_with_cast_check = true:error
109 | csharp_style_pattern_matching_over_as_with_null_check = true:error
110 |
111 | # C# code style settings - Inlined variable declaration
112 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#inlined-variable-declarations
113 | csharp_style_inlined_variable_declaration = true:error
114 |
115 | # C# code style settings - C# expression-level preferences
116 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#c-expression-level-preferences
117 | csharp_prefer_simple_default_expression = true:suggestion
118 |
119 | # C# code style settings - C# null-checking preferences
120 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#c-null-checking-preferences
121 | csharp_style_throw_expression = true:warning
122 | csharp_style_conditional_delegate_call = true:warning
123 |
124 | # C# code style settings - Code block preferences
125 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#code-block-preferences
126 | csharp_prefer_braces = when_multiline:suggestion
127 |
128 | # C# code style - Unused value preferences
129 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#unused-value-preferences
130 | csharp_style_unused_value_expression_statement_preference = discard_variable:suggestion
131 | csharp_style_unused_value_assignment_preference = discard_variable:suggestion
132 |
133 | # C# code style - Index and range preferences
134 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#index-and-range-preferences
135 | csharp_style_prefer_index_operator = true:warning
136 | csharp_style_prefer_range_operator = true:suggestion
137 |
138 | # C# code style - Miscellaneous preferences
139 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-language-conventions?view=vs-2019#miscellaneous-preferences
140 | csharp_style_deconstructed_variable_declaration = true:suggestion
141 | csharp_style_pattern_local_over_anonymous_function = true:suggestion
142 | csharp_using_directive_placement = outside_namespace:warning
143 | csharp_prefer_static_local_function = true:suggestion
144 | csharp_prefer_simple_using_statement = false:suggestion
145 | csharp_style_prefer_switch_expression = true:suggestion
146 |
147 | # .NET formatting settings - Organize using directives
148 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-formatting-conventions?view=vs-2019#organize-using-directives
149 | dotnet_sort_system_directives_first = true
150 | dotnet_separate_import_directive_groups = false
151 |
152 | # C# formatting settings - New-line options
153 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-formatting-conventions?view=vs-2019#new-line-options
154 | csharp_new_line_before_open_brace = all
155 | csharp_new_line_before_else = true
156 | csharp_new_line_before_catch = true
157 | csharp_new_line_before_finally = true
158 | csharp_new_line_before_members_in_object_initializers = true
159 | csharp_new_line_before_members_in_anonymous_types = true
160 | csharp_new_line_between_query_expression_clauses = true
161 |
162 | # C# formatting settings - Indentation options
163 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-formatting-conventions?view=vs-2019#indentation-options
164 | csharp_indent_case_contents = true
165 | csharp_indent_switch_labels = true
166 | csharp_indent_labels = one_less_than_current
167 | csharp_indent_block_contents = true
168 | csharp_indent_braces = false
169 | csharp_indent_case_contents_when_block = false
170 |
171 | # C# formatting settings - Spacing options
172 | csharp_space_after_cast = false
173 | csharp_space_after_keywords_in_control_flow_statements = true
174 | csharp_space_between_parentheses = false
175 | csharp_space_before_colon_in_inheritance_clause = true
176 | csharp_space_after_colon_in_inheritance_clause = true
177 | csharp_space_around_binary_operators = before_and_after
178 | csharp_space_between_method_declaration_parameter_list_parentheses = false
179 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
180 | csharp_space_between_method_declaration_name_and_open_parenthesis = false
181 | csharp_space_between_method_call_parameter_list_parentheses = false
182 | csharp_space_between_method_call_empty_parameter_list_parentheses = false
183 | csharp_space_between_method_call_name_and_opening_parenthesis = false
184 | csharp_space_after_comma = true
185 | csharp_space_before_comma = false
186 | csharp_space_after_dot = false
187 | csharp_space_before_dot = false
188 | csharp_space_after_semicolon_in_for_statement = true
189 | csharp_space_before_semicolon_in_for_statement = false
190 | csharp_space_around_declaration_statements = false
191 | csharp_space_before_open_square_brackets = false
192 | csharp_space_between_empty_square_brackets = false
193 | csharp_space_between_square_brackets = false
194 |
195 | # C# formatting settings - Wrap options
196 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-formatting-conventions?view=vs-2019#wrap-options
197 | csharp_preserve_single_line_blocks = true
198 | csharp_preserve_single_line_statements = false
199 |
200 | # C# formatting settings - Namespace options
201 | csharp_style_namespace_declarations = file_scoped:warning
202 |
203 | ########## name all private fields using camelCase with underscore prefix ##########
204 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-naming-conventions?view=vs-2019
205 | # dotnet_naming_rule..symbols =
206 | dotnet_naming_rule.private_fields_with_underscore.symbols = private_fields
207 |
208 | # dotnet_naming_symbols.. =
209 | dotnet_naming_symbols.private_fields.applicable_kinds = field
210 | dotnet_naming_symbols.private_fields.applicable_accessibilities = private
211 |
212 | # dotnet_naming_rule..style =
213 | dotnet_naming_rule.private_fields_with_underscore.style = prefix_underscore
214 |
215 | # dotnet_naming_style.. =
216 | dotnet_naming_style.prefix_underscore.capitalization = camel_case
217 | dotnet_naming_style.prefix_underscore.required_prefix = _
218 |
219 | # dotnet_naming_rule..severity =
220 | dotnet_naming_rule.private_fields_with_underscore.severity = warning
221 |
222 | ########## name all constant fields using UPPER_CASE ##########
223 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-naming-conventions?view=vs-2019
224 | # dotnet_naming_rule..symbols =
225 | dotnet_naming_rule.constant_fields_should_be_upper_case.symbols = constant_fields
226 |
227 | # dotnet_naming_symbols.. =
228 | dotnet_naming_symbols.constant_fields.applicable_kinds = field
229 | dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
230 | dotnet_naming_symbols.constant_fields.required_modifiers = const
231 |
232 | # dotnet_naming_rule..style =
233 | dotnet_naming_rule.constant_fields_should_be_upper_case.style = upper_case_style
234 |
235 | # dotnet_naming_style.. =
236 | dotnet_naming_style.upper_case_style.capitalization = all_upper
237 | dotnet_naming_style.upper_case_style.word_separator = _
238 |
239 | # dotnet_naming_rule..severity =
240 | dotnet_naming_rule.constant_fields_should_be_upper_case.severity = warning
241 |
242 | ########## Async methods should have "Async" suffix ##########
243 | # https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-naming-conventions?view=vs-2019
244 | # dotnet_naming_rule..symbols =
245 | dotnet_naming_rule.async_methods_end_in_async.symbols = any_async_methods
246 |
247 | # dotnet_naming_symbols.. =
248 | dotnet_naming_symbols.any_async_methods.applicable_kinds = method
249 | dotnet_naming_symbols.any_async_methods.applicable_accessibilities = *
250 | dotnet_naming_symbols.any_async_methods.required_modifiers = async
251 |
252 | # dotnet_naming_rule..style =
253 | dotnet_naming_rule.async_methods_end_in_async.style = end_in_async_style
254 |
255 | # dotnet_naming_style.. =
256 | dotnet_naming_style.end_in_async_style.capitalization = pascal_case
257 | dotnet_naming_style.end_in_async_style.word_separator =
258 | dotnet_naming_style.end_in_async_style.required_prefix =
259 | dotnet_naming_style.end_in_async_style.required_suffix = Async
260 |
261 | # dotnet_naming_rule..severity =
262 | dotnet_naming_rule.async_methods_end_in_async.severity = warning
263 |
264 | # Remove unnecessary import https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0005
265 | dotnet_diagnostic.IDE0005.severity = warning
266 |
--------------------------------------------------------------------------------