SchemeJsonConverter.cs 3.7 KB

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