A game about forced loneliness, made by TACStudios
at master 121 lines 4.2 kB view raw
1using System; 2using System.Collections.Generic; 3using System.Globalization; 4using System.Linq; 5 6////REVIEW: why is this public? 7 8////TODO: add array support 9 10////TODO: switch parsing to use to Substring 11 12namespace UnityEngine.InputSystem.Utilities 13{ 14 /// <summary> 15 /// A combination of a name and an optional list of named parameter values. For example, "Clamp(min=1,max=2)". 16 /// </summary> 17 public struct NameAndParameters 18 { 19 public string name { get; set; } 20 public ReadOnlyArray<NamedValue> parameters { get; set; } 21 22 public override string ToString() 23 { 24 if (parameters.Count == 0) 25 return name; 26 var parameterString = string.Join(NamedValue.Separator, parameters.Select(x => x.ToString()).ToArray()); 27 return $"{name}({parameterString})"; 28 } 29 30 public static IEnumerable<NameAndParameters> ParseMultiple(string text) 31 { 32 List<NameAndParameters> list = null; 33 if (!ParseMultiple(text, ref list)) 34 return Enumerable.Empty<NameAndParameters>(); 35 return list; 36 } 37 38 internal static bool ParseMultiple(string text, ref List<NameAndParameters> list) 39 { 40 text = text.Trim(); 41 if (string.IsNullOrEmpty(text)) 42 return false; 43 44 if (list == null) 45 list = new List<NameAndParameters>(); 46 else 47 list.Clear(); 48 49 var index = 0; 50 var textLength = text.Length; 51 52 while (index < textLength) 53 list.Add(ParseNameAndParameters(text, ref index)); 54 55 return true; 56 } 57 58 internal static string ParseName(string text) 59 { 60 if (text == null) 61 throw new ArgumentNullException(nameof(text)); 62 var index = 0; 63 return ParseNameAndParameters(text, ref index, true).name; 64 } 65 66 public static NameAndParameters Parse(string text) 67 { 68 if (text == null) 69 throw new ArgumentNullException(nameof(text)); 70 var index = 0; 71 return ParseNameAndParameters(text, ref index); 72 } 73 74 private static NameAndParameters ParseNameAndParameters(string text, ref int index, bool nameOnly = false) 75 { 76 var textLength = text.Length; 77 78 // Skip whitespace. 79 while (index < textLength && char.IsWhiteSpace(text[index])) 80 ++index; 81 82 // Parse name. 83 var nameStart = index; 84 while (index < textLength) 85 { 86 var nextChar = text[index]; 87 if (nextChar == '(' || nextChar == NamedValue.Separator[0] || char.IsWhiteSpace(nextChar)) 88 break; 89 ++index; 90 } 91 if (index - nameStart == 0) 92 throw new ArgumentException($"Expecting name at position {nameStart} in '{text}'", nameof(text)); 93 var name = text.Substring(nameStart, index - nameStart); 94 if (nameOnly) 95 return new NameAndParameters {name = name}; 96 97 // Skip whitespace. 98 while (index < textLength && char.IsWhiteSpace(text[index])) 99 ++index; 100 101 // Parse parameters. 102 NamedValue[] parameters = null; 103 if (index < textLength && text[index] == '(') 104 { 105 ++index; 106 var closeParenIndex = text.IndexOf(')', index); 107 if (closeParenIndex == -1) 108 throw new ArgumentException($"Expecting ')' after '(' at position {index} in '{text}'", nameof(text)); 109 110 var parameterString = text.Substring(index, closeParenIndex - index); 111 parameters = NamedValue.ParseMultiple(parameterString); 112 index = closeParenIndex + 1; 113 } 114 115 if (index < textLength && (text[index] == ',' || text[index] == InputBinding.Separator)) 116 ++index; 117 118 return new NameAndParameters {name = name, parameters = new ReadOnlyArray<NamedValue>(parameters)}; 119 } 120 } 121}