ConcurrentDictionaryJsonConverter.cs 2.3 KB

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