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 }