A game about forced loneliness, made by TACStudios
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}