From d0f49046734b82c9ea00a985832c7bdaa2460755 Mon Sep 17 00:00:00 2001
From: Henrik Widlund <4659350+henrikwidlund@users.noreply.github.com>
Date: Mon, 12 Jun 2023 20:54:12 +0200
Subject: [PATCH 1/2] Add JsonConverter generator.
---
README.md | 78 ++++
.../EnumJsonConverterAttribute.cs | 41 ++
.../JsonConverterGenerator.cs | 165 ++++++++
.../JsonConverterToGenerate.cs | 39 ++
.../SourceGenerationHelper.cs | 139 +++++++
.../StringHelper.cs | 44 ++
.../Program.cs | 73 ++++
.../Enums.cs | 17 +
.../JsonConverterTests.cs | 150 +++++++
...scapades.EnumGenerators.NetStandard.csproj | 1 +
.../JsonConverterGeneratorTests.cs | 382 ++++++++++++++++++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...onsInChildNamespace_CamelCase.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...space_CamelCase_CaseSensitive.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...se_CaseSensitive_PropertyName.verified.txt | 68 ++++
...espace_CamelCase_PropertyName.verified.txt | 68 ++++
...nChildNamespace_CaseSensitive.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...ce_CaseSensitive_PropertyName.verified.txt | 68 ++++
...tensionsInChildNamespace_None.verified.txt | 66 +++
...InChildNamespace_PropertyName.verified.txt | 68 ++++
...llowMatchingMetadataAttribute.verified.txt | 63 +++
...etadataAttribute_PropertyName.verified.txt | 65 +++
...nsInGlobalNamespace_CamelCase.verified.txt | 63 +++
...llowMatchingMetadataAttribute.verified.txt | 63 +++
...etadataAttribute_PropertyName.verified.txt | 65 +++
...space_CamelCase_CaseSensitive.verified.txt | 63 +++
...llowMatchingMetadataAttribute.verified.txt | 63 +++
...etadataAttribute_PropertyName.verified.txt | 65 +++
...se_CaseSensitive_PropertyName.verified.txt | 65 +++
...espace_CamelCase_PropertyName.verified.txt | 65 +++
...GlobalNamespace_CaseSensitive.verified.txt | 63 +++
...llowMatchingMetadataAttribute.verified.txt | 63 +++
...etadataAttribute_PropertyName.verified.txt | 65 +++
...ce_CaseSensitive_PropertyName.verified.txt | 65 +++
...ensionsInGlobalNamespace_None.verified.txt | 63 +++
...nGlobalNamespace_PropertyName.verified.txt | 65 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...nsionsInNestedClass_CamelCase.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...Class_CamelCase_CaseSensitive.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...se_CaseSensitive_PropertyName.verified.txt | 68 ++++
...dClass_CamelCase_PropertyName.verified.txt | 68 ++++
...nsInNestedClass_CaseSensitive.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...ss_CaseSensitive_PropertyName.verified.txt | 68 ++++
...mExtensionsInNestedClass_None.verified.txt | 66 +++
...onsInNestedClass_PropertyName.verified.txt | 68 ++++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...sionsWithCustomName_CamelCase.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...mName_CamelCase_CaseSensitive.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...se_CaseSensitive_PropertyName.verified.txt | 68 ++++
...omName_CamelCase_PropertyName.verified.txt | 68 ++++
...sWithCustomName_CaseSensitive.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...me_CaseSensitive_PropertyName.verified.txt | 68 ++++
...ExtensionsWithCustomName_None.verified.txt | 66 +++
...nsWithCustomName_PropertyName.verified.txt | 68 ++++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...tomNamespaceAndName_CamelCase.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...dName_CamelCase_CaseSensitive.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...se_CaseSensitive_PropertyName.verified.txt | 68 ++++
...ndName_CamelCase_PropertyName.verified.txt | 68 ++++
...amespaceAndName_CaseSensitive.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...me_CaseSensitive_PropertyName.verified.txt | 68 ++++
...thCustomNamespaceAndName_None.verified.txt | 66 +++
...NamespaceAndName_PropertyName.verified.txt | 68 ++++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...WithCustomNamespace_CamelCase.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...space_CamelCase_CaseSensitive.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...se_CaseSensitive_PropertyName.verified.txt | 68 ++++
...espace_CamelCase_PropertyName.verified.txt | 68 ++++
...CustomNamespace_CaseSensitive.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...ce_CaseSensitive_PropertyName.verified.txt | 68 ++++
...sionsWithCustomNamespace_None.verified.txt | 66 +++
...hCustomNamespace_PropertyName.verified.txt | 68 ++++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...ionsWithDisplayName_CamelCase.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...yName_CamelCase_CaseSensitive.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...se_CaseSensitive_PropertyName.verified.txt | 68 ++++
...ayName_CamelCase_PropertyName.verified.txt | 68 ++++
...WithDisplayName_CaseSensitive.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...me_CaseSensitive_PropertyName.verified.txt | 68 ++++
...xtensionsWithDisplayName_None.verified.txt | 66 +++
...sWithDisplayName_PropertyName.verified.txt | 68 ++++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...WithSameDisplayName_CamelCase.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...yName_CamelCase_CaseSensitive.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...se_CaseSensitive_PropertyName.verified.txt | 68 ++++
...ayName_CamelCase_PropertyName.verified.txt | 68 ++++
...SameDisplayName_CaseSensitive.verified.txt | 66 +++
...llowMatchingMetadataAttribute.verified.txt | 66 +++
...etadataAttribute_PropertyName.verified.txt | 68 ++++
...me_CaseSensitive_PropertyName.verified.txt | 68 ++++
...sionsWithSameDisplayName_None.verified.txt | 66 +++
...hSameDisplayName_PropertyName.verified.txt | 68 ++++
...neratesJsonConverterCorrectly.verified.txt | 68 ++++
.../SourceGenerationHelperSnapshotTests.cs | 24 ++
141 files changed, 9749 insertions(+)
create mode 100644 src/NetEscapades.EnumGenerators.Attributes/EnumJsonConverterAttribute.cs
create mode 100644 src/NetEscapades.EnumGenerators/JsonConverterGenerator.cs
create mode 100644 src/NetEscapades.EnumGenerators/JsonConverterToGenerate.cs
create mode 100644 src/NetEscapades.EnumGenerators/StringHelper.cs
create mode 100644 tests/NetEscapades.EnumGenerators.IntegrationTests/JsonConverterTests.cs
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/JsonConverterGeneratorTests.cs
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_None.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_None.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_None.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_None.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_CamelCase.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_CamelCase_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_CamelCase_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_CamelCase_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_CamelCase_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_None.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespaceAndName_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_CamelCase.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_CamelCase_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_CamelCase_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_CamelCase_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_CamelCase_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_None.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomNamespace_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_CamelCase.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_CamelCase_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_CamelCase_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_CamelCase_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_CamelCase_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_None.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithDisplayName_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_CamelCase.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_CamelCase_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_CamelCase_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_CamelCase_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_CamelCase_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_CaseSensitive.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_CaseSensitive_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_None.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithSameDisplayName_PropertyName.verified.txt
create mode 100644 tests/NetEscapades.EnumGenerators.Tests/Snapshots/SourceGenerationHelperSnapshotTests.GeneratesJsonConverterCorrectly.verified.txt
diff --git a/README.md b/README.md
index 06cd4e8..cc237eb 100644
--- a/README.md
+++ b/README.md
@@ -159,6 +159,84 @@ Note that if you provide a `[Display]` or `[Description]` attribute, the value y
You can override the name of the extension class by setting `ExtensionClassName` in the attribute and/or the namespace of the class by setting `ExtensionClassNamespace`. By default, the class will be public if the enum is public, otherwise it will be internal.
+If you want a `JsonConverter` that uses the generated extensions for efficient serialization and deserialization you can add the `EnumJsonConverter` and `JsonConverter` to the enum. For example:
+```csharp
+using System.ComponentModel.DataAnnotations;
+using System.Text.Json.Serialization;
+
+[EnumExtensions]
+[EnumJsonConverter(typeof(MyEnumConverter))]
+[JsonConverter(typeof(MyEnumConverter))]
+public enum MyEnum
+{
+ First,
+ [Display(Name = "2nd")] Second
+}
+```
+
+This will generate a class called `MyEnumConverter`. For example:
+```csharp
+///
+/// Converts a to or from JSON.
+///
+public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+{
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+}
+```
+
+You can customize the generated code for the converter by setting the following values:
+- `CaseSensitive` - Indicates if the string representation is case sensitive when deserializing it as an enum.
+- `CamelCase` - Indicates if the value of `PropertyName` should be camel cased.
+- `AllowMatchingMetadataAttribute` - If `true`, considers the value of metadata attributes, otherwise ignores them.
+- `PropertyName` - If set, this value will be used in messages when there are problems with validation and/or serialization/deserialization occurs.
+
+
## Embedding the attributes in your project
By default, the `[EnumExtensions]` attributes referenced in your application are contained in an external dll. It is also possible to embed the attributes directly in your project, so they appear in the dll when your project is built. If you wish to do this, you must do two things:
diff --git a/src/NetEscapades.EnumGenerators.Attributes/EnumJsonConverterAttribute.cs b/src/NetEscapades.EnumGenerators.Attributes/EnumJsonConverterAttribute.cs
new file mode 100644
index 0000000..56562a1
--- /dev/null
+++ b/src/NetEscapades.EnumGenerators.Attributes/EnumJsonConverterAttribute.cs
@@ -0,0 +1,41 @@
+namespace NetEscapades.EnumGenerators
+{
+ ///
+ /// Add to enums to indicate that a JsonConverter for the enum should be generated.
+ ///
+ [System.AttributeUsage(System.AttributeTargets.Enum)]
+ [System.Diagnostics.Conditional("NETESCAPADES_ENUMGENERATORS_USAGES")]
+ public sealed class EnumJsonConverterAttribute : System.Attribute
+ {
+ ///
+ /// The converter that should be generated.
+ ///
+ public System.Type ConverterType { get; }
+
+ ///
+ /// Indicates if the string representation is case sensitive when deserializing it as an enum.
+ ///
+ public bool CaseSensitive { get; set; }
+
+ ///
+ /// Indicates if the value of should be camel cased.
+ ///
+ public bool CamelCase { get; set; }
+
+ ///
+ /// If , considers the value of metadata attributes, otherwise ignores them.
+ ///
+ public bool AllowMatchingMetadataAttribute { get; set; }
+
+ ///
+ /// If set, this value will be used in messages when there are problems with validation and/or serialization/deserialization occurs.
+ ///
+ public string? PropertyName { get; set; }
+
+ ///
+ /// Creates an instance of .
+ ///
+ /// The converter to generate.
+ public EnumJsonConverterAttribute(System.Type converterType) => ConverterType = converterType;
+ }
+}
\ No newline at end of file
diff --git a/src/NetEscapades.EnumGenerators/JsonConverterGenerator.cs b/src/NetEscapades.EnumGenerators/JsonConverterGenerator.cs
new file mode 100644
index 0000000..51ce283
--- /dev/null
+++ b/src/NetEscapades.EnumGenerators/JsonConverterGenerator.cs
@@ -0,0 +1,165 @@
+using System.Text;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Text;
+
+namespace NetEscapades.EnumGenerators
+{
+ [Generator]
+ public class JsonConverterGenerator : IIncrementalGenerator
+ {
+ private const string EnumJsonConverterAttribute = "NetEscapades.EnumGenerators.EnumJsonConverterAttribute";
+ private const string EnumExtensionsAttribute = "NetEscapades.EnumGenerators.EnumExtensionsAttribute";
+
+ public void Initialize(IncrementalGeneratorInitializationContext context)
+ {
+ context.RegisterPostInitializationOutput(static ctx => ctx.AddSource(
+ "EnumJsonConverterAttribute.g.cs",
+ SourceText.From(SourceGenerationHelper.JsonConverterAttribute, Encoding.UTF8)));
+
+ var jsonConvertersToGenerate = context.SyntaxProvider
+ .ForAttributeWithMetadataName(
+ EnumJsonConverterAttribute,
+ static (node, _) => node is EnumDeclarationSyntax,
+ GetTypeToGenerate)
+ .Where(static m => m is not null);
+
+ context.RegisterSourceOutput(jsonConvertersToGenerate,
+ static (spc, source) => Execute(source, spc));
+ }
+
+ private static void Execute(JsonConverterToGenerate? jsonConverterToGenerate, SourceProductionContext context)
+ {
+ if (jsonConverterToGenerate is { } eg)
+ {
+ StringBuilder sb = new();
+ var result = SourceGenerationHelper.GenerateJsonConverterClass(sb, eg);
+ context.AddSource(eg.ConverterType + ".g.cs", SourceText.From(result, Encoding.UTF8));
+ }
+ }
+
+ private static JsonConverterToGenerate? GetTypeToGenerate(GeneratorAttributeSyntaxContext context,
+ CancellationToken ct)
+ {
+ if (context.TargetSymbol is not INamedTypeSymbol enumSymbol)
+ {
+ // nothing to do if this type isn't available
+ return null;
+ }
+
+ ct.ThrowIfCancellationRequested();
+
+ var extensionName = enumSymbol.Name + "Extensions";
+ var extensionNamespace = enumSymbol.ContainingNamespace.IsGlobalNamespace
+ ? string.Empty
+ : enumSymbol.ContainingNamespace.ToString();
+
+ var attributes = enumSymbol.GetAttributes();
+ var enumJsonConverterAttribute = attributes.FirstOrDefault(static ad =>
+ ad.AttributeClass?.Name == "EnumJsonConverterAttribute" ||
+ ad.AttributeClass?.ToDisplayString() == EnumJsonConverterAttribute);
+
+ if (enumJsonConverterAttribute == null)
+ return null;
+
+ var enumExtensionsAttribute = attributes.FirstOrDefault(static ad =>
+ ad.AttributeClass?.Name == "EnumExtensionsAttribute" ||
+ ad.AttributeClass?.ToDisplayString() == EnumExtensionsAttribute);
+
+ if (enumExtensionsAttribute == null)
+ return null;
+
+ foreach (var namedArgument in enumExtensionsAttribute.NamedArguments)
+ {
+ switch (namedArgument.Key)
+ {
+ case "ExtensionClassNamespace" when namedArgument.Value.Value?.ToString() is { } ns:
+ extensionNamespace = ns;
+ continue;
+ case "ExtensionClassName" when namedArgument.Value.Value?.ToString() is { } n:
+ extensionName = n;
+ break;
+ }
+ }
+
+ ProcessNamedArguments(enumJsonConverterAttribute,
+ out var caseSensitive,
+ out var camelCase,
+ out var allowMatchingMetadataAttribute,
+ out var propertyName);
+
+ ProcessConstructorArguments(enumJsonConverterAttribute,
+ out var converterNamespace,
+ out var converterType);
+
+ if (string.IsNullOrEmpty(converterType))
+ return null;
+
+ var fullyQualifiedName = enumSymbol.ToString();
+
+ return new JsonConverterToGenerate
+ (
+ extensionName,
+ fullyQualifiedName,
+ extensionNamespace,
+ converterType!,
+ converterNamespace,
+ enumSymbol.DeclaredAccessibility == Accessibility.Public,
+ caseSensitive,
+ camelCase,
+ allowMatchingMetadataAttribute,
+ propertyName
+ );
+ }
+
+ private static void ProcessNamedArguments(AttributeData attributeData,
+ out bool caseSensitive,
+ out bool camelCase,
+ out bool allowMatchingMetadataAttribute,
+ out string? propertyName)
+ {
+ caseSensitive = false;
+ camelCase = false;
+ allowMatchingMetadataAttribute = false;
+ propertyName = null;
+
+ foreach (var namedArgument in attributeData.NamedArguments)
+ {
+ switch (namedArgument.Key)
+ {
+ case "CaseSensitive" when namedArgument.Value.Value?.ToString() is { } cs:
+ caseSensitive = bool.Parse(cs);
+ continue;
+ case "CamelCase" when namedArgument.Value.Value?.ToString() is { } cc:
+ camelCase = bool.Parse(cc);
+ continue;
+ case "AllowMatchingMetadataAttribute" when namedArgument.Value.Value?.ToString() is { } amma:
+ allowMatchingMetadataAttribute = bool.Parse(amma);
+ continue;
+ case "PropertyName" when namedArgument.Value.Value?.ToString() is { } pn:
+ propertyName = pn;
+ continue;
+ }
+ }
+ }
+
+ private static void ProcessConstructorArguments(AttributeData attributeData,
+ out string? converterNamespace,
+ out string? converterType)
+ {
+ if (attributeData.ConstructorArguments[0].Value is ISymbol symbol)
+ {
+ converterNamespace = !symbol.ContainingNamespace.IsGlobalNamespace
+ ? symbol.ContainingNamespace.ToString()
+ : string.Empty;
+
+ converterType = symbol.Name;
+ }
+ else
+ {
+ converterNamespace = null;
+ converterType = null;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/NetEscapades.EnumGenerators/JsonConverterToGenerate.cs b/src/NetEscapades.EnumGenerators/JsonConverterToGenerate.cs
new file mode 100644
index 0000000..888b254
--- /dev/null
+++ b/src/NetEscapades.EnumGenerators/JsonConverterToGenerate.cs
@@ -0,0 +1,39 @@
+namespace NetEscapades.EnumGenerators
+{
+ public readonly record struct JsonConverterToGenerate
+ {
+ public readonly string ExtensionName;
+ public readonly string FullyQualifiedName;
+ public readonly string ExtensionNamespace;
+ public readonly string ConverterType;
+ public readonly string? ConverterNamespace;
+ public readonly bool IsPublic;
+ public readonly bool CaseSensitive;
+ public readonly bool CamelCase;
+ public readonly bool AllowMatchingMetadataAttribute;
+ public readonly string? PropertyName;
+
+ public JsonConverterToGenerate(string extensionName,
+ string fullyQualifiedName,
+ string extensionNamespace,
+ string converterType,
+ string? converterNamespace,
+ bool isPublic,
+ bool caseSensitive,
+ bool camelCase,
+ bool allowMatchingMetadataAttribute,
+ string? propertyName)
+ {
+ ExtensionName = extensionName;
+ FullyQualifiedName = fullyQualifiedName;
+ ExtensionNamespace = extensionNamespace;
+ ConverterType = converterType;
+ ConverterNamespace = !string.IsNullOrEmpty(converterNamespace) ? converterNamespace : extensionNamespace;
+ IsPublic = isPublic;
+ CaseSensitive = caseSensitive;
+ CamelCase = camelCase;
+ AllowMatchingMetadataAttribute = allowMatchingMetadataAttribute;
+ PropertyName = propertyName;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/NetEscapades.EnumGenerators/SourceGenerationHelper.cs b/src/NetEscapades.EnumGenerators/SourceGenerationHelper.cs
index 93beb76..732aad7 100644
--- a/src/NetEscapades.EnumGenerators/SourceGenerationHelper.cs
+++ b/src/NetEscapades.EnumGenerators/SourceGenerationHelper.cs
@@ -672,4 +672,143 @@ public static string[] GetNames()
return sb.ToString();
}
+
+ internal const string JsonConverterAttribute = $$"""
+{{Header}}
+
+#if NETESCAPADES_ENUMGENERATORS_EMBED_ATTRIBUTES
+
+#if NET5_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification = "Generated by the NetEscapades.EnumGenerators source generator.")]
+#else
+ [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+#endif
+namespace NetEscapades.EnumGenerators
+{
+ ///
+ /// Add to enums to indicate that a JsonConverter for the enum should be generated.
+ ///
+ [global::System.AttributeUsage(global::System.AttributeTargets.Enum)]
+ [global::System.Diagnostics.Conditional("NETESCAPADES_ENUMGENERATORS_USAGES")]
+ public class EnumJsonConverterAttribute : System.Attribute
+ {
+ ///
+ /// The converter that should be generated.
+ ///
+ public global::System.Type ConverterType { get; }
+
+ ///
+ /// Indicates if the string representation is case sensitive when deserializing it as an enum.
+ ///
+ public bool CaseSensitive { get; set; }
+
+ ///
+ /// Indicates if the value of should be camel cased.
+ ///
+ public bool CamelCase { get; set; }
+
+ ///
+ /// If set, this value will be used in messages when there are problems with validation and/or serialization/deserialization occurs.
+ ///
+ public string? PropertyName { get; set; }
+
+ ///
+ /// Creates an instance of .
+ ///
+ /// The converter to generate.
+ public EnumJsonConverterAttribute(System.Type converterType) => ConverterType = converterType;
+ }
+}
+#endif
+""";
+
+ public static string GenerateJsonConverterClass(StringBuilder sb, JsonConverterToGenerate jsonConverterToGenerate)
+ {
+ sb.Append(Header)
+ .AppendLine()
+ .AppendLine();
+
+ if (!string.IsNullOrEmpty(jsonConverterToGenerate.ConverterNamespace))
+ sb.AppendLine($$"""
+ namespace {{jsonConverterToGenerate.ConverterNamespace}}
+ {
+ """);
+
+ sb.AppendLine($$"""
+ ///
+ /// Converts a to or from JSON.
+ ///
+ {{(jsonConverterToGenerate.IsPublic ? "public" : "internal")}} sealed class {{jsonConverterToGenerate.ConverterType}} : global::System.Text.Json.Serialization.JsonConverter
+ {
+ """);
+
+ var propertyName = jsonConverterToGenerate.PropertyName;
+ if (!string.IsNullOrEmpty(propertyName) && jsonConverterToGenerate.CamelCase)
+ propertyName = propertyName.ToCamelCase();
+
+ if (!string.IsNullOrEmpty(propertyName))
+ sb.AppendLine($""" private const string PropertyName = "{propertyName}";""")
+ .AppendLine();
+
+ var fullyQualifiedExtension = string.IsNullOrEmpty(jsonConverterToGenerate.ExtensionNamespace)
+ ? jsonConverterToGenerate.ExtensionName
+ : $"{jsonConverterToGenerate.ExtensionNamespace}.{jsonConverterToGenerate.ExtensionName}";
+
+ sb.AppendLine($$"""
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::{{jsonConverterToGenerate.FullyQualifiedName}} Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+ #if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::{{fullyQualifiedExtension}}.TryParse(source, out var enumValue, {{(jsonConverterToGenerate.CaseSensitive ? "false" : "true")}}, {{(jsonConverterToGenerate.AllowMatchingMetadataAttribute ? "true))" : "false))")}}
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", {{(string.IsNullOrEmpty(propertyName) ? "null" : "PropertyName")}}, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+ #else
+ var source = reader.GetString();
+ if (global::{{fullyQualifiedExtension}}.TryParse(source, out var enumValue, {{(jsonConverterToGenerate.CaseSensitive ? "false" : "true")}}, {{(jsonConverterToGenerate.AllowMatchingMetadataAttribute ? "true))" : "false))")}}
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", {{(string.IsNullOrEmpty(propertyName) ? "null" : "PropertyName")}}, null, null);
+ #endif
+ }
+ """)
+ .AppendLine()
+ .AppendLine($$"""
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::{{jsonConverterToGenerate.FullyQualifiedName}} value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::{{fullyQualifiedExtension}}.ToStringFast(value));
+ """)
+ .AppendLine(" }");
+
+ if (!string.IsNullOrEmpty(jsonConverterToGenerate.ConverterNamespace))
+ sb.AppendLine("}");
+
+ return sb.ToString();
+ }
}
diff --git a/src/NetEscapades.EnumGenerators/StringHelper.cs b/src/NetEscapades.EnumGenerators/StringHelper.cs
new file mode 100644
index 0000000..1f035eb
--- /dev/null
+++ b/src/NetEscapades.EnumGenerators/StringHelper.cs
@@ -0,0 +1,44 @@
+namespace NetEscapades.EnumGenerators
+{
+ public static class StringHelper
+ {
+ public static string? ToCamelCase(this string? value)
+ {
+ if (string.IsNullOrEmpty(value) || !char.IsUpper(value![0]))
+ {
+ return value;
+ }
+
+ char[] chars = value.ToCharArray();
+ FixCasing(chars);
+ return new string(chars);
+ }
+
+ private static void FixCasing(Span chars)
+ {
+ for (int i = 0; i < chars.Length; i++)
+ {
+ if (i == 1 && !char.IsUpper(chars[i]))
+ {
+ break;
+ }
+
+ bool hasNext = (i + 1 < chars.Length);
+
+ // Stop when next char is already lowercase.
+ if (i > 0 && hasNext && !char.IsUpper(chars[i + 1]))
+ {
+ // If the next char is a space, lowercase current char before exiting.
+ if (chars[i + 1] == ' ')
+ {
+ chars[i] = char.ToLowerInvariant(chars[i]);
+ }
+
+ break;
+ }
+
+ chars[i] = char.ToLowerInvariant(chars[i]);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/NetEscapades.EnumGenerators.Benchmarks/Program.cs b/tests/NetEscapades.EnumGenerators.Benchmarks/Program.cs
index 8f2674c..4e61640 100644
--- a/tests/NetEscapades.EnumGenerators.Benchmarks/Program.cs
+++ b/tests/NetEscapades.EnumGenerators.Benchmarks/Program.cs
@@ -1,5 +1,7 @@
using System.ComponentModel.DataAnnotations;
using System.Runtime.CompilerServices;
+using System.Text.Json;
+using System.Text.Json.Serialization;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using Microsoft.CodeAnalysis.Emit;
@@ -11,6 +13,8 @@
.Run(args);
[EnumExtensions]
+[EnumJsonConverter(typeof(TestEnumConverter), CaseSensitive = true, AllowMatchingMetadataAttribute = false)]
+[JsonConverter(typeof(TestEnumConverter))]
public enum TestEnum
{
First = 0,
@@ -396,4 +400,73 @@ public class EnumLengthBenchmark
[Benchmark]
[MethodImpl(MethodImplOptions.NoInlining)]
public int EnumLengthProperty() => TestEnumExtensions.Length;
+}
+
+[EnumExtensions]
+[EnumJsonConverter(typeof(TestEnumIgnoreCaseConverter), CaseSensitive = false, AllowMatchingMetadataAttribute = false)]
+[JsonConverter(typeof(TestEnumIgnoreCaseConverter))]
+public enum TestEnumIgnoreCase
+{
+ First = 0,
+ [Display(Name = "2nd")] Second = 1,
+ Third = 2
+}
+
+[MemoryDiagnoser]
+public class DeserializeIgnoreCaseBenchmark
+{
+ private const string EnumsString = """
+ ["second","Third","first","Second"]
+ """;
+
+ private static readonly char[] EnumsChars = EnumsString.ToArray();
+
+ private static readonly JsonSerializerOptions JsonSerializerOptions = new()
+ {
+ Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) }
+ };
+
+ [Benchmark(Baseline = true)]
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public TestEnumIgnoreCase[]? JsonStringEnumConverter() =>
+ JsonSerializer.Deserialize(EnumsString, JsonSerializerOptions);
+
+ [Benchmark]
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public TestEnumIgnoreCase[]? JsonStringEnumConverterSpan() =>
+ JsonSerializer.Deserialize(EnumsChars.AsSpan(), JsonSerializerOptions);
+
+ [Benchmark]
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public TestEnumIgnoreCase[]? EnumJsonConverter() => JsonSerializer.Deserialize(EnumsString);
+
+ [Benchmark]
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public TestEnumIgnoreCase[]? EnumJsonConverterSpan() =>
+ JsonSerializer.Deserialize(EnumsChars.AsSpan());
+}
+
+[MemoryDiagnoser]
+public class SerializeBenchmark
+{
+ private static readonly TestEnum[] BenchmarkEnums =
+ {
+ TestEnum.Second,
+ TestEnum.Third,
+ TestEnum.First,
+ TestEnum.Second
+ };
+
+ private static readonly JsonSerializerOptions JsonSerializerOptions = new()
+ {
+ Converters = { new JsonStringEnumConverter() }
+ };
+
+ [Benchmark(Baseline = true)]
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string JsonStringEnumConverter() => JsonSerializer.Serialize(BenchmarkEnums, JsonSerializerOptions);
+
+ [Benchmark]
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public string EnumJsonConverter() => JsonSerializer.Serialize(BenchmarkEnums);
}
\ No newline at end of file
diff --git a/tests/NetEscapades.EnumGenerators.IntegrationTests/Enums.cs b/tests/NetEscapades.EnumGenerators.IntegrationTests/Enums.cs
index c772e7b..da99eca 100644
--- a/tests/NetEscapades.EnumGenerators.IntegrationTests/Enums.cs
+++ b/tests/NetEscapades.EnumGenerators.IntegrationTests/Enums.cs
@@ -1,12 +1,15 @@
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
+using System.Text.Json.Serialization;
namespace System
{
using NetEscapades.EnumGenerators;
[EnumExtensions]
+ [EnumJsonConverter(typeof(EnumInSystemConverter), CamelCase = true, CaseSensitive = false, AllowMatchingMetadataAttribute = true, PropertyName = nameof(EnumInSystem))]
+ [JsonConverter(typeof(EnumInSystemConverter))]
public enum EnumInSystem
{
First = 0,
@@ -27,6 +30,8 @@ public class Foo
}
[EnumExtensions]
+ [EnumJsonConverter(typeof(EnumInFooConverter), CamelCase = true, CaseSensitive = false, AllowMatchingMetadataAttribute = true, PropertyName = nameof(EnumInFoo))]
+ [JsonConverter(typeof(EnumInFooConverter))]
public enum EnumInFoo
{
First = 0,
@@ -38,6 +43,8 @@ public enum EnumInFoo
namespace NetEscapades.EnumGenerators.IntegrationTests
{
[EnumExtensions]
+ [EnumJsonConverter(typeof(EnumInNamespaceConverter), CamelCase = true, CaseSensitive = false, AllowMatchingMetadataAttribute = true, PropertyName = nameof(EnumInNamespace))]
+ [JsonConverter(typeof(EnumInNamespaceConverter))]
public enum EnumInNamespace
{
First = 0,
@@ -46,6 +53,8 @@ public enum EnumInNamespace
}
[EnumExtensions]
+ [EnumJsonConverter(typeof(EnumWithDisplayNameInNamespaceConverter), CamelCase = true, CaseSensitive = false, AllowMatchingMetadataAttribute = true, PropertyName = nameof(EnumWithDisplayNameInNamespace))]
+ [JsonConverter(typeof(EnumWithDisplayNameInNamespaceConverter))]
public enum EnumWithDisplayNameInNamespace
{
First = 0,
@@ -57,6 +66,8 @@ public enum EnumWithDisplayNameInNamespace
}
[EnumExtensions]
+ [EnumJsonConverter(typeof(EnumWithDescriptionInNamespaceConverter), CamelCase = true, CaseSensitive = false, AllowMatchingMetadataAttribute = true, PropertyName = nameof(EnumWithDescriptionInNamespace))]
+ [JsonConverter(typeof(EnumWithDescriptionInNamespaceConverter))]
public enum EnumWithDescriptionInNamespace
{
First = 0,
@@ -68,6 +79,8 @@ public enum EnumWithDescriptionInNamespace
}
[EnumExtensions]
+ [EnumJsonConverter(typeof(EnumWithSameDisplayNameConverter), CamelCase = true, CaseSensitive = false, AllowMatchingMetadataAttribute = true, PropertyName = nameof(EnumWithSameDisplayName))]
+ [JsonConverter(typeof(EnumWithSameDisplayNameConverter))]
public enum EnumWithSameDisplayName
{
First = 0,
@@ -80,6 +93,8 @@ public enum EnumWithSameDisplayName
}
[EnumExtensions]
+ [EnumJsonConverter(typeof(LongEnumConverter), CamelCase = true, CaseSensitive = false, AllowMatchingMetadataAttribute = true, PropertyName = nameof(LongEnum))]
+ [JsonConverter(typeof(LongEnumConverter))]
public enum LongEnum: long
{
First = 0,
@@ -88,6 +103,8 @@ public enum LongEnum: long
}
[EnumExtensions]
+ [EnumJsonConverter(typeof(FlagEnumsConverter), CamelCase = true, CaseSensitive = false, AllowMatchingMetadataAttribute = true, PropertyName = nameof(FlagsEnum))]
+ [JsonConverter(typeof(FlagEnumsConverter))]
[Flags]
public enum FlagsEnum
{
diff --git a/tests/NetEscapades.EnumGenerators.IntegrationTests/JsonConverterTests.cs b/tests/NetEscapades.EnumGenerators.IntegrationTests/JsonConverterTests.cs
new file mode 100644
index 0000000..cbff014
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.IntegrationTests/JsonConverterTests.cs
@@ -0,0 +1,150 @@
+using System;
+using System.Text.Json;
+using FluentAssertions;
+using Xunit;
+
+namespace NetEscapades.EnumGenerators.IntegrationTests;
+
+public class JsonConverterTests
+{
+ public static TheoryData ValuesToParse() => new()
+ {
+ "First",
+ "Second",
+ "2nd",
+ "2ND",
+ "first",
+ "SECOND",
+ "3",
+ "267",
+ "-267",
+ "2147483647",
+ "3000000000",
+ "Fourth",
+ "Fifth"
+ };
+
+ [Theory]
+ [MemberData(nameof(ValuesToParse))]
+ public void GeneratedJsonConverterEnumInNamespace(string name)
+ {
+ var modelWithString = new ModelWithString(name);
+ var json = JsonSerializer.Serialize(modelWithString);
+#if READONLYSPAN
+ if (EnumInNamespaceExtensions.TryParse(name.AsSpan(), out var parsed, true, true))
+#else
+ if (EnumInNamespaceExtensions.TryParse(name, out var parsed, true, true))
+#endif
+ {
+ var modelWithEnum = JsonSerializer.Deserialize>(json);
+ modelWithEnum.Should().NotBeNull();
+ modelWithEnum!.EnumProperty.Should().Be(parsed);
+ }
+ else
+ {
+ var action = () => JsonSerializer.Deserialize>(json);
+ action.Should().Throw();
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(ValuesToParse))]
+ public void GeneratedJsonConverterEnumWithDisplayNameInNamespace(string name)
+ {
+ var modelWithString = new ModelWithString(name);
+ var json = JsonSerializer.Serialize(modelWithString);
+
+#if READONLYSPAN
+ if (EnumWithDisplayNameInNamespaceExtensions.TryParse(name.AsSpan(), out var parsed, true, true))
+#else
+ if (EnumWithDisplayNameInNamespaceExtensions.TryParse(name, out var parsed, true, true))
+#endif
+ {
+ var modelWithEnum = JsonSerializer.Deserialize>(json);
+ modelWithEnum.Should().NotBeNull();
+ modelWithEnum!.EnumProperty.Should().Be(parsed);
+ }
+ else
+ {
+ var action = () => JsonSerializer.Deserialize>(json);
+ action.Should().Throw();
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(ValuesToParse))]
+ public void GeneratedJsonConverterEnumWithSameDisplayName(string name)
+ {
+ var modelWithString = new ModelWithString(name);
+ var json = JsonSerializer.Serialize(modelWithString);
+
+#if READONLYSPAN
+ if (EnumWithSameDisplayNameExtensions.TryParse(name.AsSpan(), out var parsed, true, true))
+#else
+ if (EnumWithSameDisplayNameExtensions.TryParse(name, out var parsed, true, true))
+#endif
+ {
+ var modelWithEnum = JsonSerializer.Deserialize>(json);
+ modelWithEnum.Should().NotBeNull();
+ modelWithEnum!.EnumProperty.Should().Be(parsed);
+ }
+ else
+ {
+ var action = () => JsonSerializer.Deserialize>(json);
+ action.Should().Throw();
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(ValuesToParse))]
+ public void GeneratedJsonConverterFlagsEnum(string name)
+ {
+ var modelWithString = new ModelWithString(name);
+ var json = JsonSerializer.Serialize(modelWithString);
+
+#if READONLYSPAN
+ if (FlagsEnumExtensions.TryParse(name.AsSpan(), out var parsed, true, true))
+#else
+ if (FlagsEnumExtensions.TryParse(name, out var parsed, true, true))
+#endif
+ {
+ var modelWithEnum = JsonSerializer.Deserialize>(json);
+ modelWithEnum.Should().NotBeNull();
+ modelWithEnum!.EnumProperty.Should().Be(parsed);
+ }
+ else
+ {
+ var action = () => JsonSerializer.Deserialize>(json);
+ action.Should().Throw();
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(ValuesToParse))]
+ public void GeneratedJsonConverterLongEnum(string name)
+ {
+ var modelWithString = new ModelWithString(name);
+ var json = JsonSerializer.Serialize(modelWithString);
+
+#if READONLYSPAN
+ if (LongEnumExtensions.TryParse(name.AsSpan(), out var parsed, true, true))
+#else
+ if (LongEnumExtensions.TryParse(name, out var parsed, true, true))
+#endif
+ {
+ var modelWithEnum = JsonSerializer.Deserialize>(json);
+ modelWithEnum.Should().NotBeNull();
+ modelWithEnum!.EnumProperty.Should().Be(parsed);
+ }
+ else
+ {
+ var action = () => JsonSerializer.Deserialize>(json);
+ action.Should().Throw();
+ }
+ }
+
+ private sealed record ModelWithString(string EnumProperty);
+
+ private sealed record ModelWithEnum(TEnum EnumProperty)
+ where TEnum : struct, Enum;
+}
\ No newline at end of file
diff --git a/tests/NetEscapades.EnumGenerators.NetStandard/NetEscapades.EnumGenerators.NetStandard.csproj b/tests/NetEscapades.EnumGenerators.NetStandard/NetEscapades.EnumGenerators.NetStandard.csproj
index d73e493..e47ea87 100644
--- a/tests/NetEscapades.EnumGenerators.NetStandard/NetEscapades.EnumGenerators.NetStandard.csproj
+++ b/tests/NetEscapades.EnumGenerators.NetStandard/NetEscapades.EnumGenerators.NetStandard.csproj
@@ -17,5 +17,6 @@
+
diff --git a/tests/NetEscapades.EnumGenerators.Tests/JsonConverterGeneratorTests.cs b/tests/NetEscapades.EnumGenerators.Tests/JsonConverterGeneratorTests.cs
new file mode 100644
index 0000000..3336ee2
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/JsonConverterGeneratorTests.cs
@@ -0,0 +1,382 @@
+using System;
+using System.Threading.Tasks;
+using VerifyXunit;
+using Xunit;
+
+namespace NetEscapades.EnumGenerators.Tests;
+
+[UsesVerify]
+public class JsonConverterGeneratorTests
+{
+ [Flags]
+ public enum TestParameters
+ {
+ None = 0,
+ CamelCase = 1 << 0,
+ CaseSensitive = 1 << 1,
+ AllowMatchingMetadataAttribute = 1 << 2,
+ PropertyName = 1 << 3
+ }
+
+ [Theory]
+ [InlineData(TestParameters.None)]
+ [InlineData(TestParameters.CamelCase)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.PropertyName)]
+ public Task CanGenerateEnumExtensionsInGlobalNamespace(TestParameters testParameters)
+ {
+ var (camelCase, caseSensitive, allowMatchingMetadataAttribute, propertyName) = GetTestSettings(testParameters);
+ var input = $$"""
+using System.Text.Json.Serialization;
+using NetEscapades.EnumGenerators;
+
+[EnumExtensions]
+[EnumJsonConverterAttribute(typeof(MyEnumConverter), CamelCase = {{camelCase}}, CaseSensitive = {{caseSensitive}}, AllowMatchingMetadataAttribute = {{allowMatchingMetadataAttribute}}{{propertyName}}]
+[JsonConverter(typeof(MyEnumConverter))]
+public enum MyEnum
+{
+ First,
+ Second
+}
+""";
+ var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input);
+
+ Assert.Empty(diagnostics);
+ return Verifier.Verify(output).UseTextForParameters(GetParametersText(testParameters)).UseDirectory("Snapshots");
+ }
+
+ [Theory]
+ [InlineData(TestParameters.None)]
+ [InlineData(TestParameters.CamelCase)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.PropertyName)]
+ public Task CanGenerateEnumExtensionsInChildNamespace(TestParameters testParameters)
+ {
+ var (camelCase, caseSensitive, allowMatchingMetadataAttribute, propertyName) = GetTestSettings(testParameters);
+ var input = $$"""
+using System.Text.Json.Serialization;
+using NetEscapades.EnumGenerators;
+
+namespace MyTestNameSpace
+{
+ [EnumExtensions]
+ [EnumJsonConverterAttribute(typeof(MyEnumConverter), CamelCase = {{camelCase}}, CaseSensitive = {{caseSensitive}}, AllowMatchingMetadataAttribute = {{allowMatchingMetadataAttribute}}{{propertyName}}]
+ [JsonConverter(typeof(MyEnumConverter))]
+ public enum MyEnum
+ {
+ First = 0,
+ Second = 1
+ }
+}
+""";
+ var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input);
+
+ Assert.Empty(diagnostics);
+ return Verifier.Verify(output).UseTextForParameters(GetParametersText(testParameters)).UseDirectory("Snapshots");
+ }
+
+ [Theory]
+ [InlineData(TestParameters.None)]
+ [InlineData(TestParameters.CamelCase)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.PropertyName)]
+ public Task CanGenerateEnumExtensionsInNestedClass(TestParameters testParameters)
+ {
+ var (camelCase, caseSensitive, allowMatchingMetadataAttribute, propertyName) = GetTestSettings(testParameters);
+ var input = $$"""
+using System.Text.Json.Serialization;
+using NetEscapades.EnumGenerators;
+
+namespace MyTestNameSpace
+{
+ public class InnerClass
+ {
+ [EnumExtensions]
+ [EnumJsonConverterAttribute(typeof(MyEnumConverter), CamelCase = {{camelCase}}, CaseSensitive = {{caseSensitive}}, AllowMatchingMetadataAttribute = {{allowMatchingMetadataAttribute}}{{propertyName}}]
+ [JsonConverter(typeof(MyEnumConverter))]
+ internal enum MyEnum
+ {
+ First = 0,
+ Second = 1
+ }
+ }
+}
+""";
+ var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input);
+
+ Assert.Empty(diagnostics);
+ return Verifier.Verify(output).UseTextForParameters(GetParametersText(testParameters)).UseDirectory("Snapshots");
+ }
+
+ [Theory]
+ [InlineData(TestParameters.None)]
+ [InlineData(TestParameters.CamelCase)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.PropertyName)]
+ public Task CanGenerateEnumExtensionsWithCustomName(TestParameters testParameters)
+ {
+ var (camelCase, caseSensitive, allowMatchingMetadataAttribute, propertyName) = GetTestSettings(testParameters);
+ var input = $$"""
+using System.Text.Json.Serialization;
+using NetEscapades.EnumGenerators;
+
+namespace MyTestNameSpace
+{
+ [EnumExtensions(ExtensionClassName = "A")]
+ [EnumJsonConverterAttribute(typeof(MyEnumConverter), CamelCase = {{camelCase}}, CaseSensitive = {{caseSensitive}}, AllowMatchingMetadataAttribute = {{allowMatchingMetadataAttribute}}{{propertyName}}]
+ [JsonConverter(typeof(MyEnumConverter))]
+ internal enum MyEnum
+ {
+ First = 0,
+ Second = 1
+ }
+}
+""";
+ var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input);
+
+ Assert.Empty(diagnostics);
+ return Verifier.Verify(output).UseTextForParameters(GetParametersText(testParameters)).UseDirectory("Snapshots");
+ }
+
+ [Theory]
+ [InlineData(TestParameters.None)]
+ [InlineData(TestParameters.CamelCase)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.PropertyName)]
+ public Task CanGenerateEnumExtensionsWithCustomNamespace(TestParameters testParameters)
+ {
+ var (camelCase, caseSensitive, allowMatchingMetadataAttribute, propertyName) = GetTestSettings(testParameters);
+ var input = $$"""
+using System.Text.Json.Serialization;
+using NetEscapades.EnumGenerators;
+
+namespace MyTestNameSpace
+{
+ [EnumExtensions(ExtensionClassNamespace = "A.B")]
+ [EnumJsonConverterAttribute(typeof(MyEnumConverter), CamelCase = {{camelCase}}, CaseSensitive = {{caseSensitive}}, AllowMatchingMetadataAttribute = {{allowMatchingMetadataAttribute}}{{propertyName}}]
+ [JsonConverter(typeof(MyEnumConverter))]
+ internal enum MyEnum
+ {
+ First = 0,
+ Second = 1
+ }
+}
+""";
+ var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input);
+
+ Assert.Empty(diagnostics);
+ return Verifier.Verify(output).UseTextForParameters(GetParametersText(testParameters)).UseDirectory("Snapshots");
+ }
+
+ [Theory]
+ [InlineData(TestParameters.None)]
+ [InlineData(TestParameters.CamelCase)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.PropertyName)]
+ public Task CanGenerateEnumExtensionsWithCustomNamespaceAndName(TestParameters testParameters)
+ {
+ var (camelCase, caseSensitive, allowMatchingMetadataAttribute, propertyName) = GetTestSettings(testParameters);
+ var input = $$"""
+using System.Text.Json.Serialization;
+using NetEscapades.EnumGenerators;
+
+namespace MyTestNameSpace
+{
+ [EnumExtensions(ExtensionClassNamespace = "A.B", ExtensionClassName = "C")]
+ [EnumJsonConverterAttribute(typeof(MyEnumConverter), CamelCase = {{camelCase}}, CaseSensitive = {{caseSensitive}}, AllowMatchingMetadataAttribute = {{allowMatchingMetadataAttribute}}{{propertyName}}]
+ [JsonConverter(typeof(MyEnumConverter))]
+ internal enum MyEnum
+ {
+ First = 0,
+ Second = 1
+ }
+}
+""";
+ var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input);
+
+ Assert.Empty(diagnostics);
+ return Verifier.Verify(output).UseTextForParameters(GetParametersText(testParameters)).UseDirectory("Snapshots");
+ }
+
+ [Theory]
+ [InlineData(TestParameters.None)]
+ [InlineData(TestParameters.CamelCase)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.PropertyName)]
+ public Task CanGenerateEnumExtensionsWithDisplayName(TestParameters testParameters)
+ {
+ var (camelCase, caseSensitive, allowMatchingMetadataAttribute, propertyName) = GetTestSettings(testParameters);
+ var input = $$"""
+using System.Text.Json.Serialization;
+using NetEscapades.EnumGenerators;
+using System.ComponentModel.DataAnnotations;
+
+namespace MyTestNameSpace
+{
+ [EnumExtensions]
+ [EnumJsonConverterAttribute(typeof(MyEnumConverter), CamelCase = {{camelCase}}, CaseSensitive = {{caseSensitive}}, AllowMatchingMetadataAttribute = {{allowMatchingMetadataAttribute}}{{propertyName}}]
+ [JsonConverter(typeof(MyEnumConverter))]
+ public enum MyEnum
+ {
+ First = 0,
+
+ [Display(Name = "2nd")]
+ Second = 1,
+ Third = 2,
+
+ [Display(Name = "4th")]
+ Fourth = 3
+ }
+}
+""";
+ var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input);
+
+ Assert.Empty(diagnostics);
+ return Verifier.Verify(output).UseTextForParameters(GetParametersText(testParameters)).UseDirectory("Snapshots");
+ }
+
+ [Theory]
+ [InlineData(TestParameters.None)]
+ [InlineData(TestParameters.CamelCase)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CamelCase | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CamelCase | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.PropertyName)]
+ [InlineData(TestParameters.CaseSensitive | TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute)]
+ [InlineData(TestParameters.AllowMatchingMetadataAttribute | TestParameters.PropertyName)]
+ [InlineData(TestParameters.PropertyName)]
+ public Task CanGenerateEnumExtensionsWithSameDisplayName(TestParameters testParameters)
+ {
+ var (camelCase, caseSensitive, allowMatchingMetadataAttribute, propertyName) = GetTestSettings(testParameters);
+ var input = $$"""
+using System.Text.Json.Serialization;
+using NetEscapades.EnumGenerators;
+using System.ComponentModel.DataAnnotations;
+
+namespace MyTestNameSpace
+{
+ [EnumExtensions]
+ [EnumJsonConverterAttribute(typeof(MyEnumConverter), CamelCase = {{camelCase}}, CaseSensitive = {{caseSensitive}}, AllowMatchingMetadataAttribute = {{allowMatchingMetadataAttribute}}{{propertyName}}]
+ [JsonConverter(typeof(MyEnumConverter))]
+ public enum MyEnum
+ {
+ First = 0,
+
+ [Display(Name = "2nd")]
+ Second = 1,
+ Third = 2,
+
+ [Display(Name = "2nd")]
+ Fourth = 3
+ }
+}
+""";
+ var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input);
+
+ Assert.Empty(diagnostics);
+ return Verifier.Verify(output).UseTextForParameters(GetParametersText(testParameters)).UseDirectory("Snapshots");
+ }
+
+ private static string GetParametersText(TestParameters testParameters) =>
+ testParameters.ToString().Replace(", ", "_");
+
+ private static (string CamelCase, string CaseSensitive, string AllowMatchingMetadataAttribute, string PropertyName)
+ GetTestSettings(TestParameters testParameters) =>
+ (
+ (testParameters & TestParameters.CamelCase) != 0 ? "true" : "false",
+ (testParameters & TestParameters.CaseSensitive) != 0 ? "true" : "false",
+ (testParameters & TestParameters.AllowMatchingMetadataAttribute) != 0 ? "true" : "false",
+ (testParameters & TestParameters.PropertyName) != 0 ? """, PropertyName = "Bla")""" : ")"
+ );
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_AllowMatchingMetadataAttribute.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_AllowMatchingMetadataAttribute.verified.txt
new file mode 100644
index 0000000..ef45b9c
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_AllowMatchingMetadataAttribute.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_AllowMatchingMetadataAttribute_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_AllowMatchingMetadataAttribute_PropertyName.verified.txt
new file mode 100644
index 0000000..58c30c5
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_AllowMatchingMetadataAttribute_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "Bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase.verified.txt
new file mode 100644
index 0000000..4a6f48f
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_AllowMatchingMetadataAttribute.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_AllowMatchingMetadataAttribute.verified.txt
new file mode 100644
index 0000000..ef45b9c
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_AllowMatchingMetadataAttribute.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
new file mode 100644
index 0000000..d8ea8de
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive.verified.txt
new file mode 100644
index 0000000..dec6cf0
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
new file mode 100644
index 0000000..08d39de
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
new file mode 100644
index 0000000..e89d911
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive_PropertyName.verified.txt
new file mode 100644
index 0000000..7cf6f53
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_CaseSensitive_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_PropertyName.verified.txt
new file mode 100644
index 0000000..4accbff
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CamelCase_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive.verified.txt
new file mode 100644
index 0000000..dec6cf0
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
new file mode 100644
index 0000000..08d39de
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
new file mode 100644
index 0000000..b16b77c
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "Bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive_PropertyName.verified.txt
new file mode 100644
index 0000000..7bd995d
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_CaseSensitive_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "Bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_None.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_None.verified.txt
new file mode 100644
index 0000000..4a6f48f
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_None.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_PropertyName.verified.txt
new file mode 100644
index 0000000..52ba81f
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInChildNamespace_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "Bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_AllowMatchingMetadataAttribute.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_AllowMatchingMetadataAttribute.verified.txt
new file mode 100644
index 0000000..7c6586b
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_AllowMatchingMetadataAttribute.verified.txt
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_AllowMatchingMetadataAttribute_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_AllowMatchingMetadataAttribute_PropertyName.verified.txt
new file mode 100644
index 0000000..ed65d7f
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_AllowMatchingMetadataAttribute_PropertyName.verified.txt
@@ -0,0 +1,65 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "Bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase.verified.txt
new file mode 100644
index 0000000..bf6643f
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase.verified.txt
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_AllowMatchingMetadataAttribute.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_AllowMatchingMetadataAttribute.verified.txt
new file mode 100644
index 0000000..7c6586b
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_AllowMatchingMetadataAttribute.verified.txt
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
new file mode 100644
index 0000000..151d740
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
@@ -0,0 +1,65 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive.verified.txt
new file mode 100644
index 0000000..cd6eac8
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive.verified.txt
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
new file mode 100644
index 0000000..59af3fa
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
new file mode 100644
index 0000000..8e33e2b
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
@@ -0,0 +1,65 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive_PropertyName.verified.txt
new file mode 100644
index 0000000..a896c3c
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_CaseSensitive_PropertyName.verified.txt
@@ -0,0 +1,65 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_PropertyName.verified.txt
new file mode 100644
index 0000000..b999e40
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CamelCase_PropertyName.verified.txt
@@ -0,0 +1,65 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive.verified.txt
new file mode 100644
index 0000000..cd6eac8
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive.verified.txt
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
new file mode 100644
index 0000000..59af3fa
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
new file mode 100644
index 0000000..de61119
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
@@ -0,0 +1,65 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "Bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive_PropertyName.verified.txt
new file mode 100644
index 0000000..a4297e5
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_CaseSensitive_PropertyName.verified.txt
@@ -0,0 +1,65 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "Bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_None.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_None.verified.txt
new file mode 100644
index 0000000..bf6643f
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_None.verified.txt
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_PropertyName.verified.txt
new file mode 100644
index 0000000..e38dc14
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInGlobalNamespace_PropertyName.verified.txt
@@ -0,0 +1,65 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+ ///
+ /// Converts a to or from JSON.
+ ///
+ public sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "Bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyEnumExtensions.ToStringFast(value));
+ }
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_AllowMatchingMetadataAttribute.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_AllowMatchingMetadataAttribute.verified.txt
new file mode 100644
index 0000000..784d0cd
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_AllowMatchingMetadataAttribute.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_AllowMatchingMetadataAttribute_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_AllowMatchingMetadataAttribute_PropertyName.verified.txt
new file mode 100644
index 0000000..c6a62c9
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_AllowMatchingMetadataAttribute_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "Bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase.verified.txt
new file mode 100644
index 0000000..7908c6d
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_AllowMatchingMetadataAttribute.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_AllowMatchingMetadataAttribute.verified.txt
new file mode 100644
index 0000000..784d0cd
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_AllowMatchingMetadataAttribute.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
new file mode 100644
index 0000000..31ee853
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive.verified.txt
new file mode 100644
index 0000000..c52b017
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
new file mode 100644
index 0000000..67d0c80
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
new file mode 100644
index 0000000..314af16
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive_PropertyName.verified.txt
new file mode 100644
index 0000000..a5ff316
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_CaseSensitive_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_PropertyName.verified.txt
new file mode 100644
index 0000000..85421ea
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CamelCase_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive.verified.txt
new file mode 100644
index 0000000..c52b017
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
new file mode 100644
index 0000000..67d0c80
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive_AllowMatchingMetadataAttribute.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
new file mode 100644
index 0000000..0876279
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive_AllowMatchingMetadataAttribute_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "Bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive_PropertyName.verified.txt
new file mode 100644
index 0000000..821c9ec
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_CaseSensitive_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "Bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_None.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_None.verified.txt
new file mode 100644
index 0000000..7908c6d
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_None.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_PropertyName.verified.txt
new file mode 100644
index 0000000..abc55df
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsInNestedClass_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "Bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.InnerClass.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.MyEnumExtensions.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.InnerClass.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.MyEnumExtensions.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_AllowMatchingMetadataAttribute.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_AllowMatchingMetadataAttribute.verified.txt
new file mode 100644
index 0000000..095f0e6
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_AllowMatchingMetadataAttribute.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.A.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.A.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.A.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_AllowMatchingMetadataAttribute_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_AllowMatchingMetadataAttribute_PropertyName.verified.txt
new file mode 100644
index 0000000..e7e9620
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_AllowMatchingMetadataAttribute_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "Bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.A.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.A.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.A.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase.verified.txt
new file mode 100644
index 0000000..73ed1b3
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.A.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.A.TryParse(source, out var enumValue, true, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.A.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_AllowMatchingMetadataAttribute.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_AllowMatchingMetadataAttribute.verified.txt
new file mode 100644
index 0000000..095f0e6
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_AllowMatchingMetadataAttribute.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.A.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.A.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.A.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
new file mode 100644
index 0000000..6a0bc31
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_AllowMatchingMetadataAttribute_PropertyName.verified.txt
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ private const string PropertyName = "bla";
+
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.A.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", PropertyName, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.A.TryParse(source, out var enumValue, true, true))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", PropertyName, null, null);
+#endif
+ }
+
+ ///
+ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestNameSpace.MyEnum value, global::System.Text.Json.JsonSerializerOptions options)
+ => writer.WriteStringValue(global::MyTestNameSpace.A.ToStringFast(value));
+ }
+}
diff --git a/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_CaseSensitive.verified.txt b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_CaseSensitive.verified.txt
new file mode 100644
index 0000000..5e123bc
--- /dev/null
+++ b/tests/NetEscapades.EnumGenerators.Tests/Snapshots/JsonConverterGeneratorTests.CanGenerateEnumExtensionsWithCustomName_CamelCase_CaseSensitive.verified.txt
@@ -0,0 +1,66 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by the NetEscapades.EnumGenerators source generator
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#nullable enable
+
+namespace MyTestNameSpace
+{
+ ///
+ /// Converts a to or from JSON.
+ ///
+ internal sealed class MyEnumConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ ///
+ ///
+ /// Read and convert the JSON to .
+ ///
+ ///
+ /// A converter may throw any Exception, but should throw when the JSON is invalid.
+ ///
+ public override global::MyTestNameSpace.MyEnum Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
+ char[]? rentedBuffer = null;
+ var bufferLength = reader.HasValueSequence ? checked((int)reader.ValueSequence.Length) : reader.ValueSpan.Length;
+
+ var charBuffer = bufferLength <= 128
+ ? stackalloc char[128]
+ : rentedBuffer = global::System.Buffers.ArrayPool.Shared.Rent(bufferLength);
+
+ var charsWritten = reader.CopyString(charBuffer);
+ global::System.ReadOnlySpan source = charBuffer[..charsWritten];
+ try
+ {
+ if (global::MyTestNameSpace.A.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source.ToString()} is not a valid value.", null, null, null);
+ }
+ finally
+ {
+ if (rentedBuffer is not null)
+ {
+ charBuffer[..charsWritten].Clear();
+ global::System.Buffers.ArrayPool.Shared.Return(rentedBuffer);
+ }
+ }
+#else
+ var source = reader.GetString();
+ if (global::MyTestNameSpace.A.TryParse(source, out var enumValue, false, false))
+ return enumValue;
+
+ throw new global::System.Text.Json.JsonException($"{source} is not a valid value.", null, null, null);
+#endif
+ }
+
+ ///