ConcurrentDictionaryJsonConverter.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #nullable disable
  2. using System.Collections.Concurrent;
  3. using System.Diagnostics.CodeAnalysis;
  4. using System.Text.Json;
  5. using System.Text.Json.Serialization;
  6. namespace Terminal.Gui.Configuration;
  7. [RequiresUnreferencedCode("AOT")]
  8. internal class ConcurrentDictionaryJsonConverter<T> : JsonConverter<ConcurrentDictionary<string, T>>
  9. {
  10. public override ConcurrentDictionary<string, T> Read(
  11. ref Utf8JsonReader reader,
  12. Type typeToConvert,
  13. JsonSerializerOptions options
  14. )
  15. {
  16. if (reader.TokenType != JsonTokenType.StartArray)
  17. {
  18. throw new JsonException($"Expected a JSON array (\"[ {{ ... }} ]\"), but got \"{reader.TokenType}\".");
  19. }
  20. // If the Json options indicate ignoring case, use the invariant culture ignore case comparer
  21. ConcurrentDictionary<string, T> dictionary = new (
  22. options.PropertyNameCaseInsensitive
  23. ? StringComparer.InvariantCultureIgnoreCase
  24. : StringComparer.InvariantCulture);
  25. while (reader.Read())
  26. {
  27. if (reader.TokenType == JsonTokenType.StartObject)
  28. {
  29. reader.Read();
  30. if (reader.TokenType == JsonTokenType.PropertyName)
  31. {
  32. string key = reader.GetString();
  33. reader.Read();
  34. object value = JsonSerializer.Deserialize(ref reader, typeof(T), ConfigurationManager.SerializerContext);
  35. dictionary.TryAdd(key, (T)value);
  36. }
  37. }
  38. else if (reader.TokenType == JsonTokenType.EndArray)
  39. {
  40. break;
  41. }
  42. }
  43. return dictionary;
  44. }
  45. public override void Write(Utf8JsonWriter writer, ConcurrentDictionary<string, T> value, JsonSerializerOptions options)
  46. {
  47. writer.WriteStartArray();
  48. foreach (KeyValuePair<string, T> item in value)
  49. {
  50. writer.WriteStartObject();
  51. writer.WritePropertyName(item.Key);
  52. JsonSerializer.Serialize(writer, item.Value, typeof(T), ConfigurationManager.SerializerContext);
  53. writer.WriteEndObject();
  54. }
  55. writer.WriteEndArray();
  56. }
  57. }