AttributeJsonConverter.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using System.Diagnostics.CodeAnalysis;
  2. using System.Text.Json;
  3. using System.Text.Json.Serialization;
  4. namespace Terminal.Gui.Configuration;
  5. /// <summary>Json converter from the <see cref="Attribute"/> class.</summary>
  6. [RequiresUnreferencedCode ("AOT")]
  7. internal class AttributeJsonConverter : JsonConverter<Attribute>
  8. {
  9. private static AttributeJsonConverter? _instance;
  10. /// <summary></summary>
  11. public static AttributeJsonConverter Instance
  12. {
  13. get
  14. {
  15. if (_instance is null)
  16. {
  17. _instance = new AttributeJsonConverter ();
  18. }
  19. return _instance;
  20. }
  21. }
  22. public override Attribute Read (ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
  23. {
  24. if (reader.TokenType != JsonTokenType.StartObject)
  25. {
  26. throw new JsonException ($"Unexpected StartObject token when parsing Attribute: {reader.TokenType}.");
  27. }
  28. var attribute = new Attribute ();
  29. Color? foreground = null;
  30. Color? background = null;
  31. TextStyle? style = null;
  32. string propertyName = string.Empty;
  33. while (reader.Read ())
  34. {
  35. if (reader.TokenType == JsonTokenType.EndObject)
  36. {
  37. if (foreground is null || background is null)
  38. {
  39. throw new JsonException ($"{propertyName}: Both Foreground and Background colors must be provided.");
  40. }
  41. if (style.HasValue)
  42. {
  43. return new Attribute (foreground.Value, background.Value, style.Value);
  44. }
  45. else
  46. {
  47. return new Attribute (foreground.Value, background.Value);
  48. }
  49. }
  50. if (reader.TokenType != JsonTokenType.PropertyName)
  51. {
  52. throw new JsonException ($"{propertyName}: Unexpected token when parsing Attribute: {reader.TokenType}.");
  53. }
  54. propertyName = reader.GetString ()!;
  55. reader.Read ();
  56. var property = $"\"{reader.GetString ()}\"";
  57. try
  58. {
  59. switch (propertyName?.ToLower ())
  60. {
  61. case "foreground":
  62. foreground = JsonSerializer.Deserialize (property, ConfigurationManager.SerializerContext.Color);
  63. break;
  64. case "background":
  65. background = JsonSerializer.Deserialize (property, ConfigurationManager.SerializerContext.Color);
  66. break;
  67. case "style":
  68. style = JsonSerializer.Deserialize (property, ConfigurationManager.SerializerContext.TextStyle);
  69. break;
  70. default:
  71. throw new JsonException ($"{propertyName}: Unknown Attribute property .");
  72. }
  73. }
  74. catch (JsonException ex)
  75. {
  76. throw new JsonException ($"{propertyName}: \"{property}\" - {ex.Message}");
  77. }
  78. }
  79. throw new JsonException ($"{propertyName}: Bad Attribute.");
  80. }
  81. public override void Write (Utf8JsonWriter writer, Attribute value, JsonSerializerOptions options)
  82. {
  83. writer.WriteStartObject ();
  84. writer.WritePropertyName (nameof (Attribute.Foreground));
  85. ColorJsonConverter.Instance.Write (writer, value.Foreground, options);
  86. writer.WritePropertyName (nameof (Attribute.Background));
  87. ColorJsonConverter.Instance.Write (writer, value.Background, options);
  88. if (value.Style != TextStyle.None)
  89. {
  90. writer.WritePropertyName (nameof (Attribute.Style));
  91. JsonSerializer.Serialize (writer, value.Style, ConfigurationManager.SerializerContext.TextStyle);
  92. }
  93. writer.WriteEndObject ();
  94. }
  95. }