-
-
Notifications
You must be signed in to change notification settings - Fork 144
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
231191e
commit 2e83808
Showing
2 changed files
with
115 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
src/Verify/Serialization/CustomContractResolver_Dictionary.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
partial class CustomContractResolver | ||
{ | ||
protected override JsonDictionaryContract CreateDictionaryContract(Type objectType) | ||
{ | ||
var contract = base.CreateDictionaryContract(objectType); | ||
contract.DictionaryKeyResolver = (_, name, original) => ResolveDictionaryKey(contract, name, original); | ||
if (settings.SortDictionaries) | ||
{ | ||
contract.OrderByKey = true; | ||
} | ||
|
||
contract.InterceptSerializeItem = HandleDictionaryItem; | ||
|
||
return contract; | ||
} | ||
|
||
KeyValueInterceptResult HandleDictionaryItem(JsonWriter writer, object key, object? value) | ||
{ | ||
if (key is string stringKey && | ||
settings.TryGetScrubOrIgnoreByName(stringKey, out var scrubOrIgnore)) | ||
{ | ||
return ToInterceptKeyValueResult(scrubOrIgnore.Value); | ||
} | ||
|
||
if (value is not null && | ||
settings.TryGetScrubOrIgnoreByInstance(value, out scrubOrIgnore)) | ||
{ | ||
return ToInterceptKeyValueResult(scrubOrIgnore.Value); | ||
} | ||
|
||
return KeyValueInterceptResult.Default; | ||
} | ||
|
||
static KeyValueInterceptResult ToInterceptKeyValueResult(ScrubOrIgnore scrubOrIgnore) | ||
{ | ||
if (scrubOrIgnore == ScrubOrIgnore.Ignore) | ||
{ | ||
return KeyValueInterceptResult.Ignore; | ||
} | ||
|
||
return KeyValueInterceptResult.ReplaceValue("{Scrubbed}"); | ||
} | ||
|
||
string ResolveDictionaryKey(JsonDictionaryContract contract, string name, object original) | ||
{ | ||
var counter = Counter.Current; | ||
var keyType = contract.DictionaryKeyType; | ||
|
||
#if NET6_0_OR_GREATER | ||
|
||
if (original is Date date) | ||
{ | ||
if (settings.TryConvert(counter, date, out var result)) | ||
{ | ||
return result; | ||
} | ||
} | ||
|
||
if (original is Time time) | ||
{ | ||
if (settings.TryConvert(counter, time, out var result)) | ||
{ | ||
return result; | ||
} | ||
} | ||
|
||
#endif | ||
|
||
if (original is Guid guid) | ||
{ | ||
if (settings.TryConvert(counter, guid, out var result)) | ||
{ | ||
return result; | ||
} | ||
} | ||
|
||
if (original is string stringValue) | ||
{ | ||
if (settings.TryParseConvert(counter, stringValue.AsSpan(), out var result)) | ||
{ | ||
return result; | ||
} | ||
} | ||
|
||
if (original is DateTime dateTime) | ||
{ | ||
if (settings.TryConvert(counter, dateTime, out var result)) | ||
{ | ||
return result; | ||
} | ||
} | ||
|
||
if (original is DateTimeOffset dateTimeOffset) | ||
{ | ||
if (settings.TryConvert(counter, dateTimeOffset, out var result)) | ||
{ | ||
return result; | ||
} | ||
} | ||
|
||
if (keyType == typeof(Type)) | ||
{ | ||
var type = Type.GetType(name); | ||
if (type is null) | ||
{ | ||
throw new($"Could not load type `{name}`."); | ||
} | ||
|
||
return type.SimpleName(); | ||
} | ||
|
||
return name; | ||
} | ||
} |