From 591a76e34fd0a60100eaf120819547bcdd3cb002 Mon Sep 17 00:00:00 2001 From: Tig Date: Tue, 24 Sep 2024 22:45:37 -0600 Subject: [PATCH] Fixed Run Json --- .../Configuration/RuneJsonConverter.cs | 42 +++--- Terminal.Gui/Drawing/Glyphs.cs | 124 +----------------- Terminal.Gui/Input/Key.cs | 1 - UnitTests/Configuration/JsonConverterTests.cs | 13 +- .../Configuration/RuneJsonConverterTests.cs | 76 +++++++++++ .../SerializableConfigurationPropertyTests.cs | 2 +- 6 files changed, 119 insertions(+), 139 deletions(-) diff --git a/Terminal.Gui/Configuration/RuneJsonConverter.cs b/Terminal.Gui/Configuration/RuneJsonConverter.cs index 4b364f252..f6a6b1612 100644 --- a/Terminal.Gui/Configuration/RuneJsonConverter.cs +++ b/Terminal.Gui/Configuration/RuneJsonConverter.cs @@ -6,9 +6,18 @@ using System.Text.RegularExpressions; namespace Terminal.Gui; /// -/// Json converter for . Supports Json converter for . Supports A string as -/// one of: - unicode char (e.g. "☑") - U+hex format (e.g. "U+2611") - \u format (e.g. "\\u2611") A number - The -/// unicode code in decimal +/// Json converter for . +/// +/// If the Rune is printable, it will be serialized as the glyph; otherwise the \u format (e.g. "\\u2611") is used. +/// +/// +/// Supports deserializing a string as +/// one of: +/// - unicode char (e.g. "☑") +/// - U+hex format (e.g. "U+2611") +/// - \u format (e.g. "\\u2611") +/// - A decimal number (e.g. "97" for "a") +/// /// internal class RuneJsonConverter : JsonConverter { @@ -108,7 +117,7 @@ internal class RuneJsonConverter : JsonConverter throw new JsonException ($"Invalid combined Rune ({value})"); } - return new Rune (combined [0]); + return new (combined [0]); } case JsonTokenType.Number: { @@ -116,7 +125,7 @@ internal class RuneJsonConverter : JsonConverter if (Rune.IsValid (num)) { - return new Rune (num); + return new (num); } throw new JsonException ($"Invalid Rune (not a scalar Unicode value): {num}."); @@ -128,18 +137,17 @@ internal class RuneJsonConverter : JsonConverter public override void Write (Utf8JsonWriter writer, Rune value, JsonSerializerOptions options) { - // HACK: Writes a JSON comment in addition to the glyph to ease debugging. - // Technically, JSON comments are not valid, but we use relaxed decoding - // (ReadCommentHandling = JsonCommentHandling.Skip) - //writer.WriteCommentValue ($"(U+{value.Value:X8})"); - //var printable = value.MakePrintable (); - //if (printable == Rune.ReplacementChar) { - // writer.WriteStringValue (value.ToString ()); - //} else { - // //writer.WriteRawValue ($"\"{value}\""); - //} - - writer.WriteNumberValue (value.Value); + Rune printable = value.MakePrintable (); + if (printable == Rune.ReplacementChar) + { + // Write as /u string + writer.WriteRawValue ($"\"{value}\""); + } + else + { + // Write as the actual glyph + writer.WriteStringValue (value.ToString ()); + } } } #pragma warning restore 1591 diff --git a/Terminal.Gui/Drawing/Glyphs.cs b/Terminal.Gui/Drawing/Glyphs.cs index d3190d2f5..fdf024307 100644 --- a/Terminal.Gui/Drawing/Glyphs.cs +++ b/Terminal.Gui/Drawing/Glyphs.cs @@ -1,6 +1,4 @@ -using System.Text.Json.Serialization; - -namespace Terminal.Gui; +namespace Terminal.Gui; /// Defines the standard set of glyphs used to draw checkboxes, lines, borders, etc... /// @@ -20,157 +18,119 @@ namespace Terminal.Gui; public class GlyphDefinitions { /// File icon. Defaults to ☰ (Trigram For Heaven) - [JsonConverter (typeof (RuneJsonConverter))] public Rune File { get; set; } = (Rune)'☰'; /// Folder icon. Defaults to ꤉ (Kayah Li Digit Nine) - [JsonConverter (typeof (RuneJsonConverter))] public Rune Folder { get; set; } = (Rune)'꤉'; /// Horizontal Ellipsis - … U+2026 - [JsonConverter (typeof (RuneJsonConverter))] public Rune HorizontalEllipsis { get; set; } = (Rune)'…'; /// Vertical Four Dots - ⁞ U+205e - [JsonConverter (typeof (RuneJsonConverter))] public Rune VerticalFourDots { get; set; } = (Rune)'⁞'; #region ----------------- Single Glyphs ----------------- - /// Checked indicator (e.g. for and ) - Ballot Box With Check - ☑ U+02611. - [JsonConverter (typeof (RuneJsonConverter))] + /// Checked indicator (e.g. for and ). public Rune CheckStateChecked { get; set; } = (Rune)'☑'; /// Not Checked indicator (e.g. for and ). - [JsonConverter (typeof (RuneJsonConverter))] public Rune CheckStateUnChecked { get; set; } = (Rune)'☐'; - /// Null Checked indicator (e.g. for and ). - Ballot Box With X - ☒ U+02612. - [JsonConverter (typeof (RuneJsonConverter))] + /// Null Checked indicator (e.g. for and ). public Rune CheckStateNone { get; set; } = (Rune)'☒'; /// Selected indicator (e.g. for and ). - [JsonConverter (typeof (RuneJsonConverter))] public Rune Selected { get; set; } = (Rune)'◉'; /// Not Selected indicator (e.g. for and ). - [JsonConverter (typeof (RuneJsonConverter))] public Rune UnSelected { get; set; } = (Rune)'○'; /// Horizontal arrow. - [JsonConverter (typeof (RuneJsonConverter))] public Rune RightArrow { get; set; } = (Rune)'►'; /// Left arrow. - [JsonConverter (typeof (RuneJsonConverter))] public Rune LeftArrow { get; set; } = (Rune)'◄'; /// Down arrow. - [JsonConverter (typeof (RuneJsonConverter))] public Rune DownArrow { get; set; } = (Rune)'▼'; /// Vertical arrow. - [JsonConverter (typeof (RuneJsonConverter))] public Rune UpArrow { get; set; } = (Rune)'▲'; /// Left default indicator (e.g. for . - [JsonConverter (typeof (RuneJsonConverter))] public Rune LeftDefaultIndicator { get; set; } = (Rune)'►'; /// Horizontal default indicator (e.g. for . - [JsonConverter (typeof (RuneJsonConverter))] public Rune RightDefaultIndicator { get; set; } = (Rune)'◄'; /// Left Bracket (e.g. for . Default is (U+005B) - [. - [JsonConverter (typeof (RuneJsonConverter))] public Rune LeftBracket { get; set; } = (Rune)'⟦'; /// Horizontal Bracket (e.g. for . Default is (U+005D) - ]. - [JsonConverter (typeof (RuneJsonConverter))] public Rune RightBracket { get; set; } = (Rune)'⟧'; /// Half block meter segment (e.g. for ). - [JsonConverter (typeof (RuneJsonConverter))] public Rune BlocksMeterSegment { get; set; } = (Rune)'▌'; /// Continuous block meter segment (e.g. for ). - [JsonConverter (typeof (RuneJsonConverter))] public Rune ContinuousMeterSegment { get; set; } = (Rune)'█'; /// Stipple pattern (e.g. for ). Default is Light Shade (U+2591) - ░. - [JsonConverter (typeof (RuneJsonConverter))] public Rune Stipple { get; set; } = (Rune)'░'; /// Diamond (e.g. for . Default is Lozenge (U+25CA) - ◊. - [JsonConverter (typeof (RuneJsonConverter))] public Rune Diamond { get; set; } = (Rune)'◊'; /// Close. Default is Heavy Ballot X (U+2718) - ✘. - [JsonConverter (typeof (RuneJsonConverter))] public Rune Close { get; set; } = (Rune)'✘'; /// Minimize. Default is Lower Horizontal Shadowed White Circle (U+274F) - ❏. - [JsonConverter (typeof (RuneJsonConverter))] public Rune Minimize { get; set; } = (Rune)'❏'; /// Maximize. Default is Upper Horizontal Shadowed White Circle (U+273D) - ✽. - [JsonConverter (typeof (RuneJsonConverter))] public Rune Maximize { get; set; } = (Rune)'✽'; /// Dot. Default is (U+2219) - ∙. - [JsonConverter (typeof (RuneJsonConverter))] public Rune Dot { get; set; } = (Rune)'∙'; /// Black Circle . Default is (U+025cf) - ●. - [JsonConverter (typeof (RuneJsonConverter))] public Rune BlackCircle { get; set; } = (Rune)'●'; // Black Circle - ● U+025cf /// Expand (e.g. for . - [JsonConverter (typeof (RuneJsonConverter))] public Rune Expand { get; set; } = (Rune)'+'; /// Expand (e.g. for . - [JsonConverter (typeof (RuneJsonConverter))] public Rune Collapse { get; set; } = (Rune)'-'; /// Identical To (U+226) - [JsonConverter (typeof (RuneJsonConverter))] public Rune IdenticalTo { get; set; } = (Rune)'≡'; /// Move indicator. Default is Lozenge (U+25CA) - ◊. - [JsonConverter (typeof (RuneJsonConverter))] public Rune Move { get; set; } = (Rune)'◊'; /// Size Horizontally indicator. Default is ┥Left Right Arrow - ↔ U+02194 - [JsonConverter (typeof (RuneJsonConverter))] public Rune SizeHorizontal { get; set; } = (Rune)'↔'; - + /// Size Vertical indicator. Default Up Down Arrow - ↕ U+02195 - [JsonConverter (typeof (RuneJsonConverter))] public Rune SizeVertical { get; set; } = (Rune)'↕'; /// Size Top Left indicator. North West Arrow - ↖ U+02196 - [JsonConverter (typeof (RuneJsonConverter))] public Rune SizeTopLeft { get; set; } = (Rune)'↖'; /// Size Top Right indicator. North East Arrow - ↗ U+02197 - [JsonConverter (typeof (RuneJsonConverter))] public Rune SizeTopRight { get; set; } = (Rune)'↗'; /// Size Bottom Right indicator. South East Arrow - ↘ U+02198 - [JsonConverter (typeof (RuneJsonConverter))] public Rune SizeBottomRight { get; set; } = (Rune)'↘'; /// Size Bottom Left indicator. South West Arrow - ↙ U+02199 - [JsonConverter (typeof (RuneJsonConverter))] public Rune SizeBottomLLeft { get; set; } = (Rune)'↙'; - + /// Apple (non-BMP). Because snek. And because it's an example of a non-BMP surrogate pair. See Issue #2610. - [JsonConverter (typeof (RuneJsonConverter))] public Rune Apple { get; set; } = "🍎".ToRunes () [0]; // nonBMP /// Apple (BMP). Because snek. See Issue #2610. - [JsonConverter (typeof (RuneJsonConverter))] public Rune AppleBMP { get; set; } = (Rune)'❦'; ///// @@ -183,123 +143,93 @@ public class GlyphDefinitions #region ----------------- Lines ----------------- /// Box Drawings Horizontal Line - Light (U+2500) - ─ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HLine { get; set; } = (Rune)'─'; /// Box Drawings Vertical Line - Light (U+2502) - │ - [JsonConverter (typeof (RuneJsonConverter))] public Rune VLine { get; set; } = (Rune)'│'; /// Box Drawings Double Horizontal (U+2550) - ═ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HLineDbl { get; set; } = (Rune)'═'; /// Box Drawings Double Vertical (U+2551) - ║ - [JsonConverter (typeof (RuneJsonConverter))] public Rune VLineDbl { get; set; } = (Rune)'║'; /// Box Drawings Heavy Double Dash Horizontal (U+254D) - ╍ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HLineHvDa2 { get; set; } = (Rune)'╍'; /// Box Drawings Heavy Triple Dash Vertical (U+2507) - ┇ - [JsonConverter (typeof (RuneJsonConverter))] public Rune VLineHvDa3 { get; set; } = (Rune)'┇'; /// Box Drawings Heavy Triple Dash Horizontal (U+2505) - ┅ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HLineHvDa3 { get; set; } = (Rune)'┅'; /// Box Drawings Heavy Quadruple Dash Horizontal (U+2509) - ┉ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HLineHvDa4 { get; set; } = (Rune)'┉'; /// Box Drawings Heavy Double Dash Vertical (U+254F) - ╏ - [JsonConverter (typeof (RuneJsonConverter))] public Rune VLineHvDa2 { get; set; } = (Rune)'╏'; /// Box Drawings Heavy Quadruple Dash Vertical (U+250B) - ┋ - [JsonConverter (typeof (RuneJsonConverter))] public Rune VLineHvDa4 { get; set; } = (Rune)'┋'; /// Box Drawings Light Double Dash Horizontal (U+254C) - ╌ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HLineDa2 { get; set; } = (Rune)'╌'; /// Box Drawings Light Triple Dash Vertical (U+2506) - ┆ - [JsonConverter (typeof (RuneJsonConverter))] public Rune VLineDa3 { get; set; } = (Rune)'┆'; /// Box Drawings Light Triple Dash Horizontal (U+2504) - ┄ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HLineDa3 { get; set; } = (Rune)'┄'; /// Box Drawings Light Quadruple Dash Horizontal (U+2508) - ┈ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HLineDa4 { get; set; } = (Rune)'┈'; /// Box Drawings Light Double Dash Vertical (U+254E) - ╎ - [JsonConverter (typeof (RuneJsonConverter))] public Rune VLineDa2 { get; set; } = (Rune)'╎'; /// Box Drawings Light Quadruple Dash Vertical (U+250A) - ┊ - [JsonConverter (typeof (RuneJsonConverter))] public Rune VLineDa4 { get; set; } = (Rune)'┊'; /// Box Drawings Heavy Horizontal (U+2501) - ━ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HLineHv { get; set; } = (Rune)'━'; /// Box Drawings Heavy Vertical (U+2503) - ┃ - [JsonConverter (typeof (RuneJsonConverter))] public Rune VLineHv { get; set; } = (Rune)'┃'; /// Box Drawings Light Left (U+2574) - ╴ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HalfLeftLine { get; set; } = (Rune)'╴'; /// Box Drawings Light Vertical (U+2575) - ╵ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HalfTopLine { get; set; } = (Rune)'╵'; /// Box Drawings Light Horizontal (U+2576) - ╶ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HalfRightLine { get; set; } = (Rune)'╶'; /// Box Drawings Light Down (U+2577) - ╷ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HalfBottomLine { get; set; } = (Rune)'╷'; /// Box Drawings Heavy Left (U+2578) - ╸ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HalfLeftLineHv { get; set; } = (Rune)'╸'; /// Box Drawings Heavy Vertical (U+2579) - ╹ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HalfTopLineHv { get; set; } = (Rune)'╹'; /// Box Drawings Heavy Horizontal (U+257A) - ╺ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HalfRightLineHv { get; set; } = (Rune)'╺'; /// Box Drawings Light Vertical and Horizontal (U+257B) - ╻ - [JsonConverter (typeof (RuneJsonConverter))] public Rune HalfBottomLineLt { get; set; } = (Rune)'╻'; /// Box Drawings Light Horizontal and Heavy Horizontal (U+257C) - ╼ - [JsonConverter (typeof (RuneJsonConverter))] public Rune RightSideLineLtHv { get; set; } = (Rune)'╼'; /// Box Drawings Light Vertical and Heavy Horizontal (U+257D) - ╽ - [JsonConverter (typeof (RuneJsonConverter))] public Rune BottomSideLineLtHv { get; set; } = (Rune)'╽'; /// Box Drawings Heavy Left and Light Horizontal (U+257E) - ╾ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LeftSideLineHvLt { get; set; } = (Rune)'╾'; /// Box Drawings Heavy Vertical and Light Horizontal (U+257F) - ╿ - [JsonConverter (typeof (RuneJsonConverter))] public Rune TopSideLineHvLt { get; set; } = (Rune)'╿'; #endregion @@ -307,35 +237,27 @@ public class GlyphDefinitions #region ----------------- Upper Left Corners ----------------- /// Box Drawings Upper Left Corner - Light Vertical and Light Horizontal (U+250C) - ┌ - [JsonConverter (typeof (RuneJsonConverter))] public Rune ULCorner { get; set; } = (Rune)'┌'; /// Box Drawings Upper Left Corner - Double (U+2554) - ╔ - [JsonConverter (typeof (RuneJsonConverter))] public Rune ULCornerDbl { get; set; } = (Rune)'╔'; /// Box Drawings Upper Left Corner - Light Arc Down and Horizontal (U+256D) - ╭ - [JsonConverter (typeof (RuneJsonConverter))] public Rune ULCornerR { get; set; } = (Rune)'╭'; /// Box Drawings Heavy Down and Horizontal (U+250F) - ┏ - [JsonConverter (typeof (RuneJsonConverter))] public Rune ULCornerHv { get; set; } = (Rune)'┏'; /// Box Drawings Down Heavy and Horizontal Light (U+251E) - ┎ - [JsonConverter (typeof (RuneJsonConverter))] public Rune ULCornerHvLt { get; set; } = (Rune)'┎'; /// Box Drawings Down Light and Horizontal Heavy (U+250D) - ┎ - [JsonConverter (typeof (RuneJsonConverter))] public Rune ULCornerLtHv { get; set; } = (Rune)'┍'; /// Box Drawings Double Down and Single Horizontal (U+2553) - ╓ - [JsonConverter (typeof (RuneJsonConverter))] public Rune ULCornerDblSingle { get; set; } = (Rune)'╓'; /// Box Drawings Single Down and Double Horizontal (U+2552) - ╒ - [JsonConverter (typeof (RuneJsonConverter))] public Rune ULCornerSingleDbl { get; set; } = (Rune)'╒'; #endregion @@ -343,35 +265,27 @@ public class GlyphDefinitions #region ----------------- Lower Left Corners ----------------- /// Box Drawings Lower Left Corner - Light Vertical and Light Horizontal (U+2514) - └ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LLCorner { get; set; } = (Rune)'└'; /// Box Drawings Heavy Vertical and Horizontal (U+2517) - ┗ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LLCornerHv { get; set; } = (Rune)'┗'; /// Box Drawings Heavy Vertical and Horizontal Light (U+2516) - ┖ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LLCornerHvLt { get; set; } = (Rune)'┖'; /// Box Drawings Vertical Light and Horizontal Heavy (U+2511) - ┕ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LLCornerLtHv { get; set; } = (Rune)'┕'; /// Box Drawings Double Vertical and Double Left (U+255A) - ╚ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LLCornerDbl { get; set; } = (Rune)'╚'; /// Box Drawings Single Vertical and Double Left (U+2558) - ╘ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LLCornerSingleDbl { get; set; } = (Rune)'╘'; /// Box Drawings Double Down and Single Left (U+2559) - ╙ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LLCornerDblSingle { get; set; } = (Rune)'╙'; /// Box Drawings Upper Left Corner - Light Arc Down and Left (U+2570) - ╰ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LLCornerR { get; set; } = (Rune)'╰'; #endregion @@ -379,35 +293,27 @@ public class GlyphDefinitions #region ----------------- Upper Right Corners ----------------- /// Box Drawings Upper Horizontal Corner - Light Vertical and Light Horizontal (U+2510) - ┐ - [JsonConverter (typeof (RuneJsonConverter))] public Rune URCorner { get; set; } = (Rune)'┐'; /// Box Drawings Upper Horizontal Corner - Double Vertical and Double Horizontal (U+2557) - ╗ - [JsonConverter (typeof (RuneJsonConverter))] public Rune URCornerDbl { get; set; } = (Rune)'╗'; /// Box Drawings Upper Horizontal Corner - Light Arc Vertical and Horizontal (U+256E) - ╮ - [JsonConverter (typeof (RuneJsonConverter))] public Rune URCornerR { get; set; } = (Rune)'╮'; /// Box Drawings Heavy Down and Left (U+2513) - ┓ - [JsonConverter (typeof (RuneJsonConverter))] public Rune URCornerHv { get; set; } = (Rune)'┓'; /// Box Drawings Heavy Vertical and Left Down Light (U+2511) - ┑ - [JsonConverter (typeof (RuneJsonConverter))] public Rune URCornerHvLt { get; set; } = (Rune)'┑'; /// Box Drawings Down Light and Horizontal Heavy (U+2514) - ┒ - [JsonConverter (typeof (RuneJsonConverter))] public Rune URCornerLtHv { get; set; } = (Rune)'┒'; /// Box Drawings Double Vertical and Single Left (U+2556) - ╖ - [JsonConverter (typeof (RuneJsonConverter))] public Rune URCornerDblSingle { get; set; } = (Rune)'╖'; /// Box Drawings Single Vertical and Double Left (U+2555) - ╕ - [JsonConverter (typeof (RuneJsonConverter))] public Rune URCornerSingleDbl { get; set; } = (Rune)'╕'; #endregion @@ -415,35 +321,27 @@ public class GlyphDefinitions #region ----------------- Lower Right Corners ----------------- /// Box Drawings Lower Right Corner - Light (U+2518) - ┘ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LRCorner { get; set; } = (Rune)'┘'; /// Box Drawings Lower Right Corner - Double (U+255D) - ╝ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LRCornerDbl { get; set; } = (Rune)'╝'; /// Box Drawings Lower Right Corner - Rounded (U+256F) - ╯ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LRCornerR { get; set; } = (Rune)'╯'; /// Box Drawings Lower Right Corner - Heavy (U+251B) - ┛ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LRCornerHv { get; set; } = (Rune)'┛'; /// Box Drawings Lower Right Corner - Double Vertical and Single Horizontal (U+255C) - ╜ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LRCornerDblSingle { get; set; } = (Rune)'╜'; /// Box Drawings Lower Right Corner - Single Vertical and Double Horizontal (U+255B) - ╛ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LRCornerSingleDbl { get; set; } = (Rune)'╛'; /// Box Drawings Lower Right Corner - Light Vertical and Heavy Horizontal (U+2519) - ┙ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LRCornerLtHv { get; set; } = (Rune)'┙'; /// Box Drawings Lower Right Corner - Heavy Vertical and Light Horizontal (U+251A) - ┚ - [JsonConverter (typeof (RuneJsonConverter))] public Rune LRCornerHvLt { get; set; } = (Rune)'┚'; #endregion @@ -539,31 +437,24 @@ public class GlyphDefinitions #region ----------------- Crosses ----------------- /// Box Drawings Cross - Single Vertical and Single Horizontal (U+253C) - ┼ - [JsonConverter (typeof (RuneJsonConverter))] public Rune Cross { get; set; } = (Rune)'┼'; /// Box Drawings Cross - Single Vertical and Double Horizontal (U+256A) - ╪ - [JsonConverter (typeof (RuneJsonConverter))] public Rune CrossDblH { get; set; } = (Rune)'╪'; /// Box Drawings Cross - Double Vertical and Single Horizontal (U+256B) - ╫ - [JsonConverter (typeof (RuneJsonConverter))] public Rune CrossDblV { get; set; } = (Rune)'╫'; /// Box Drawings Cross - Double Vertical and Double Horizontal (U+256C) - ╬ - [JsonConverter (typeof (RuneJsonConverter))] public Rune CrossDbl { get; set; } = (Rune)'╬'; /// Box Drawings Cross - Heavy Horizontal and Light Vertical (U+253F) - ┿ - [JsonConverter (typeof (RuneJsonConverter))] public Rune CrossHvH { get; set; } = (Rune)'┿'; /// Box Drawings Cross - Light Horizontal and Heavy Vertical (U+2541) - ╂ - [JsonConverter (typeof (RuneJsonConverter))] public Rune CrossHvV { get; set; } = (Rune)'╂'; /// Box Drawings Cross - Heavy Vertical and Heavy Horizontal (U+254B) - ╋ - [JsonConverter (typeof (RuneJsonConverter))] public Rune CrossHv { get; set; } = (Rune)'╋'; #endregion @@ -572,23 +463,18 @@ public class GlyphDefinitions /// Shadow - Vertical Start - Left Half Block - ▌ U+0258c - [JsonConverter (typeof (RuneJsonConverter))] public Rune ShadowVerticalStart { get; set; } = (Rune)'▖'; // Half: '\u2596' ▖; /// Shadow - Vertical - Left Half Block - ▌ U+0258c - [JsonConverter (typeof (RuneJsonConverter))] public Rune ShadowVertical { get; set; } = (Rune)'▌'; /// Shadow - Horizontal Start - Upper Half Block - ▀ U+02580 - [JsonConverter (typeof (RuneJsonConverter))] public Rune ShadowHorizontalStart { get; set; } = (Rune)'▝'; // Half: ▝ U+0259d; /// Shadow - Horizontal - Upper Half Block - ▀ U+02580 - [JsonConverter (typeof (RuneJsonConverter))] public Rune ShadowHorizontal { get; set; } = (Rune)'▀'; /// Shadow - Horizontal End - Quadrant Upper Left - ▘ U+02598 - [JsonConverter (typeof (RuneJsonConverter))] public Rune ShadowHorizontalEnd { get; set; } = (Rune)'▘'; #endregion diff --git a/Terminal.Gui/Input/Key.cs b/Terminal.Gui/Input/Key.cs index 3335f9c0d..5c92cc489 100644 --- a/Terminal.Gui/Input/Key.cs +++ b/Terminal.Gui/Input/Key.cs @@ -977,7 +977,6 @@ public class Key : EventArgs, IEquatable /// Gets or sets the separator character used when parsing and printing Keys. E.g. Ctrl+A. The default is '+'. [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] - [JsonConverter (typeof (RuneJsonConverter))] public static Rune Separator { get => _separator; diff --git a/UnitTests/Configuration/JsonConverterTests.cs b/UnitTests/Configuration/JsonConverterTests.cs index cf3531eb0..2d1262647 100644 --- a/UnitTests/Configuration/JsonConverterTests.cs +++ b/UnitTests/Configuration/JsonConverterTests.cs @@ -1,4 +1,5 @@ -using System.Text.Encodings.Web; +using System.Text; +using System.Text.Encodings.Web; using System.Text.Json; using System.Text.Unicode; @@ -341,4 +342,14 @@ public class KeyJsonConverterTests // Assert Assert.Equal (expectedStringTo, deserializedKey.ToString ()); } + + [Fact] + public void Separator_Property_Serializes_As_Glyph () + { + // Act + string json = JsonSerializer.Serialize (Key.Separator, ConfigurationManager._serializerOptions); + + // Assert + Assert.Equal ("\"+\"", json); + } } diff --git a/UnitTests/Configuration/RuneJsonConverterTests.cs b/UnitTests/Configuration/RuneJsonConverterTests.cs index 087b466ad..c0a56a5bf 100644 --- a/UnitTests/Configuration/RuneJsonConverterTests.cs +++ b/UnitTests/Configuration/RuneJsonConverterTests.cs @@ -67,4 +67,80 @@ public class RunJsonConverterTests // Assert Assert.Equal (expected, deserialized.ToString ()); } + + [Fact] + public void Printable_Rune_Is_Serialized_As_Glyph () + { + // Arrange + + // Act + string json = JsonSerializer.Serialize ((Rune)'a', ConfigurationManager._serializerOptions); + + // Assert + Assert.Equal ("\"a\"", json); + } + + [Fact] + public void Non_Printable_Rune_Is_Serialized_As_u_Encoded_Value () + { + // Arrange + + // Act + string json = JsonSerializer.Serialize ((Rune)0x01, ConfigurationManager._serializerOptions); + + // Assert + Assert.Equal ("\"\\u0001\"", json); + } + + [Fact] + public void Json_With_Glyph_Works () + { + // Arrange + var json = "\"a\""; + + // Act + var deserialized = JsonSerializer.Deserialize (json, ConfigurationManager._serializerOptions); + + // Assert + Assert.Equal ("a", deserialized.ToString ()); + } + + [Fact] + public void Json_With_u_Encoded_Works () + { + // Arrange + var json = "\"\\u0061\""; + + // Act + var deserialized = JsonSerializer.Deserialize (json, ConfigurationManager._serializerOptions); + + // Assert + Assert.Equal ("a", deserialized.ToString ()); + } + + [Fact] + public void Json_With_U_Encoded_Works () + { + // Arrange + var json = "\"U+0061\""; + + // Act + var deserialized = JsonSerializer.Deserialize (json, ConfigurationManager._serializerOptions); + + // Assert + Assert.Equal ("a", deserialized.ToString ()); + } + + [Fact] + public void Json_With_Decimal_Works () + { + // Arrange + var json = "97"; + + // Act + var deserialized = JsonSerializer.Deserialize (json, ConfigurationManager._serializerOptions); + + // Assert + Assert.Equal ("a", deserialized.ToString ()); + } } diff --git a/UnitTests/Configuration/SerializableConfigurationPropertyTests.cs b/UnitTests/Configuration/SerializableConfigurationPropertyTests.cs index d32d19cc6..bbf0fc2e6 100644 --- a/UnitTests/Configuration/SerializableConfigurationPropertyTests.cs +++ b/UnitTests/Configuration/SerializableConfigurationPropertyTests.cs @@ -46,7 +46,7 @@ public class SerializableConfigurationPropertyTests // Ensure no property has the generic JsonStringEnumConverter<> EnsureNoSpecifiedConverters (properties, new [] { typeof (JsonStringEnumConverter<>) }); - //// Ensure no property has the type RuneJsonConverter + /// Ensure no property has the type RuneJsonConverter //EnsureNoSpecifiedConverters (properties, new [] { typeof (RuneJsonConverter) }); // Ensure no property has the type KeyJsonConverter EnsureNoSpecifiedConverters (properties, new [] { typeof (KeyJsonConverter) });