SchemeJsonConverter.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #nullable enable
  2. using System.Diagnostics.CodeAnalysis;
  3. using System.Text.Json;
  4. using System.Text.Json.Serialization;
  5. namespace Terminal.Gui.Configuration;
  6. // ReSharper disable StringLiteralTypo
  7. /// <summary>Implements a JSON converter for <see cref="Drawing.Scheme"/>.</summary>
  8. [RequiresUnreferencedCode ("AOT")]
  9. internal class SchemeJsonConverter : JsonConverter<Scheme>
  10. {
  11. /// <inheritdoc/>
  12. public override Scheme Read (ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
  13. {
  14. if (reader.TokenType != JsonTokenType.StartObject)
  15. {
  16. throw new JsonException ($"Unexpected StartObject token when parsing Scheme: {reader.TokenType}.");
  17. }
  18. var scheme = new Scheme ();
  19. var propertyName = string.Empty;
  20. while (reader.Read ())
  21. {
  22. if (reader.TokenType == JsonTokenType.EndObject)
  23. {
  24. return scheme;
  25. }
  26. if (reader.TokenType != JsonTokenType.PropertyName)
  27. {
  28. throw new JsonException ($"After {propertyName}: Expected PropertyName but got another token when parsing Attribute: {reader.TokenType}.");
  29. }
  30. propertyName = reader.GetString ();
  31. reader.Read ();
  32. // Make sure attributes are marked as explicitly set when deserialized
  33. object? attrObj = JsonSerializer.Deserialize (ref reader, ConfigurationManager.SerializerContext.Attribute);
  34. if (attrObj is not Attribute attribute)
  35. {
  36. throw new JsonException ($"After {propertyName}: Expected Attribute but got {attrObj?.GetType ().Name ?? "null"} when parsing Scheme.");
  37. }
  38. if (propertyName is { })
  39. {
  40. scheme = propertyName.ToLowerInvariant () switch
  41. {
  42. "normal" => scheme with { Normal = attribute },
  43. "hotnormal" => scheme with { HotNormal = attribute },
  44. "focus" => scheme with { Focus = attribute },
  45. "hotfocus" => scheme with { HotFocus = attribute },
  46. "active" => scheme with { Active = attribute },
  47. "hotactive" => scheme with { HotActive = attribute },
  48. "highlight" => scheme with { Highlight = attribute },
  49. "editable" => scheme with { Editable = attribute },
  50. "readonly" => scheme with { ReadOnly = attribute },
  51. "disabled" => scheme with { Disabled = attribute },
  52. _ => throw new JsonException ($"{propertyName}: Unrecognized Scheme Attribute name.")
  53. };
  54. }
  55. else
  56. {
  57. throw new JsonException ("null property name.");
  58. }
  59. }
  60. throw new JsonException ($"After {propertyName}: Invalid Json.");
  61. }
  62. /// <inheritdoc/>
  63. public override void Write (Utf8JsonWriter writer, Scheme value, JsonSerializerOptions options)
  64. {
  65. writer.WriteStartObject ();
  66. foreach (VisualRole role in Enum.GetValues<VisualRole>())
  67. {
  68. // Get the attribute for the role
  69. if (!value.TryGetExplicitlySetAttributeForRole (role, out Attribute? attribute))
  70. {
  71. // Skip attributes that are not explicitly set
  72. continue;
  73. }
  74. writer.WritePropertyName (role.ToString ());
  75. // Write the attribute using the AttributeJsonConverter
  76. AttributeJsonConverter.Instance.Write (writer, attribute!.Value, options);
  77. }
  78. writer.WriteEndObject ();
  79. }
  80. }