Browse Source

Support for getting the full T set when using generic AnsiResponseParser

tznind 9 months ago
parent
commit
bdcf36c314

+ 2 - 2
Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseExpectation.cs

@@ -1,10 +1,10 @@
 #nullable enable
 namespace Terminal.Gui;
 
-public record AnsiResponseExpectation (string Terminator, Action<string> Response)
+internal record AnsiResponseExpectation (string Terminator, Action<IHeld> Response)
 {
     public bool Matches (string cur)
     {
         return cur.EndsWith (Terminator);
     }
-}
+}

+ 28 - 4
Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseParser.cs

@@ -213,7 +213,7 @@ internal abstract class AnsiResponseParserBase : IAnsiResponseParser
         {
             if (invokeCallback)
             {
-                matchingResponse.Response?.Invoke (heldContent.HeldToString ());
+                matchingResponse.Response.Invoke (heldContent);
             }
             ResetState ();
 
@@ -233,11 +233,11 @@ internal abstract class AnsiResponseParserBase : IAnsiResponseParser
     {
         if (persistent)
         {
-            persistentExpectations.Add (new (terminator, response));
+            persistentExpectations.Add (new (terminator, (h)=>response.Invoke (h.HeldToString ())));
         }
         else
         {
-            expectedResponses.Add (new (terminator, response));
+            expectedResponses.Add (new (terminator, (h) => response.Invoke (h.HeldToString ())));
         }
     }
 
@@ -287,13 +287,37 @@ internal class AnsiResponseParser<T> : AnsiResponseParserBase
 
     public IEnumerable<Tuple<char, T>> Release ()
     {
-        foreach (Tuple<char, T> h in (IEnumerable<Tuple<char, T>>)heldContent.HeldToObjects ())
+        foreach (Tuple<char, T> h in HeldToEnumerable())
         {
             yield return h;
         }
 
         ResetState ();
     }
+
+    private IEnumerable<Tuple<char, T>> HeldToEnumerable ()
+    {
+        return (IEnumerable<Tuple<char, T>>)heldContent.HeldToObjects ();
+    }
+
+    /// <summary>
+    /// 'Overload' for specifying an expectation that requires the metadata as well as characters. Has
+    /// a unique name because otherwise most lamdas will give ambiguous overload errors.
+    /// </summary>
+    /// <param name="terminator"></param>
+    /// <param name="response"></param>
+    /// <param name="persistent"></param>
+    public void ExpectResponseT (string terminator, Action<IEnumerable<Tuple<char,T>>> response, bool persistent)
+    {
+        if (persistent)
+        {
+            persistentExpectations.Add (new (terminator, (h) => response.Invoke (HeldToEnumerable ())));
+        }
+        else
+        {
+            expectedResponses.Add (new (terminator, (h) => response.Invoke (HeldToEnumerable ())));
+        }
+    }
 }
 
 internal class AnsiResponseParser : AnsiResponseParserBase

+ 41 - 1
UnitTests/ConsoleDrivers/AnsiResponseParserTests.cs

@@ -1,4 +1,6 @@
-using System.Diagnostics;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
 using System.Text;
 using Xunit.Abstractions;
 
@@ -374,6 +376,44 @@ public class AnsiResponseParserTests (ITestOutputHelper output)
         Assert.Equal (4, M);  // Expected three `M` responses plus the initial value of 1
     }
 
+    [Fact]
+    public void TestPersistentResponses_WithMetadata ()
+    {
+        var p = new AnsiResponseParser<int> ();
+
+        int m = 0;
+
+        var result = new List<Tuple<char,int>> ();
+
+        p.ExpectResponseT ("m", (r) =>
+                               {
+                                   result = r.ToList ();
+                                   m++;
+                               }, true);
+
+        // Act - Feed input strings containing ANSI sequences
+        p.ProcessInput (StringToBatch("\u001b[<0;10;10m"));  // Should match and increment `m`
+
+        // Prepare expected result: 
+        var expected = new List<Tuple<char, int>>
+        {
+            Tuple.Create('\u001b', 0), // Escape character
+            Tuple.Create('[', 1),
+            Tuple.Create('<', 2),
+            Tuple.Create('0', 3),
+            Tuple.Create(';', 4),
+            Tuple.Create('1', 5),
+            Tuple.Create('0', 6),
+            Tuple.Create(';', 7),
+            Tuple.Create('1', 8),
+            Tuple.Create('0', 9),
+            Tuple.Create('m', 10)
+        };
+
+        Assert.Equal (expected.Count, result.Count); // Ensure the count is as expected
+        Assert.True (expected.SequenceEqual (result), "The result does not match the expected output."); // Check the actual content
+    }
+
     private Tuple<char, int> [] StringToBatch (string batch)
     {
         return batch.Select ((k) => Tuple.Create (k, tIndex++)).ToArray ();