UriHelper.cs
 1  // Copyright (c) Microsoft Corporation
 2  // The Microsoft Corporation licenses this file to you under the MIT license.
 3  // See the LICENSE file in the project root for more information.
 4  
 5  namespace Microsoft.CmdPal.Ext.Bookmarks.Helpers;
 6  
 7  internal static class UriHelper
 8  {
 9      /// <summary>
10      /// Tries to split a URI string into scheme and remainder.
11      /// Scheme must be valid per RFC 3986 and followed by ':'.
12      /// </summary>
13      public static bool TryGetScheme(ReadOnlySpan<char> input, out string scheme, out string remainder)
14      {
15          // https://datatracker.ietf.org/doc/html/rfc3986#page-17
16          scheme = string.Empty;
17          remainder = string.Empty;
18  
19          if (input.Length < 2)
20          {
21              return false; // must have at least "a:"
22          }
23  
24          // Must contain ':' delimiter
25          var colonIndex = input.IndexOf(':');
26          if (colonIndex <= 0)
27          {
28              return false; // no colon or colon at start
29          }
30  
31          // First char must be a letter
32          var first = input[0];
33          if (!char.IsLetter(first))
34          {
35              return false;
36          }
37  
38          // Validate scheme part
39          for (var i = 1; i < colonIndex; i++)
40          {
41              var c = input[i];
42              if (!(char.IsLetterOrDigit(c) || c == '+' || c == '-' || c == '.'))
43              {
44                  return false;
45              }
46          }
47  
48          // Extract scheme and remainder
49          scheme = input[..colonIndex].ToString();
50          remainder = colonIndex + 1 < input.Length ? input[(colonIndex + 1)..].ToString() : string.Empty;
51          return true;
52      }
53  }