71 public string?
Value { init;
get; }
77 public string?
Key { init;
get; }
79 private List<XRepoItem> _unnamedItems = [];
80 private Dictionary<string, XRepoItem> _namedItems = [];
82 public IEnumerator<XRepoItem> GetEnumerator()
84 foreach (var item
in _unnamedItems) yield
return item;
85 foreach (var item
in _namedItems.Values) yield
return item;
88 IEnumerator IEnumerable.GetEnumerator()
90 foreach (var item
in _unnamedItems) yield
return item;
91 foreach (var item
in _namedItems.Values) yield
return item;
97 public XRepoItem?
this[
int i] => i >= 0 && i < _unnamedItems.Count ? _unnamedItems[i] :
null;
102 public XRepoItem?
this[
string i] => _namedItems.TryGetValue(i, out var output) ? output :
null;
104 private const int MinimumIndent = 4;
106 private static bool IsItemLine(
string line)
107 => !
string.IsNullOrWhiteSpace(line)
108 && line.StartsWith(
new string(
' ', MinimumIndent))
109 && line.TrimStart().StartsWithAny(
"require",
"->");
111 private static bool IsWithinCurrentItem(
string line,
int indent)
112 => !IsItemLine(line) || GetIndent(line) > indent;
114 private static int GetIndent(
string line) => line.TakeWhile(c => c ==
' ').Count();
116 private static XRepoItem Parse(ref List<string> infoOutput, ref
int i)
118 var line = infoOutput[i];
119 int indent = GetIndent(line);
120 var options = RegexOptions.IgnoreCase;
122 var packKey = line.Parse(
@"\srequire\((?<KEY>[a-z].*)\)\:", options, forceNullOnWhitespce:
true)(
"KEY");
123 var keyOnly = line.Parse(
@"\s->\s(?<KEY>[a-z]\w*)\:$", options, forceNullOnWhitespce:
true)(
"KEY");
124 var propWithValue = line.Parse(
@"\s->\s(?:(?<KEY>[a-z]\w*)\:\s)?(?<VALUE>.+)$", options, forceNullOnWhitespce:
true);
126 Kind kind = packKey !=
null ? Kind.Package
127 : keyOnly !=
null ? Kind.Key
128 : propWithValue(
"KEY") !=
null && propWithValue(
"VALUE") !=
null ? Kind.Property
129 : propWithValue(
"VALUE") !=
null ? Kind.Value
132 var key = kind
switch {
133 Kind.Package => packKey,
135 Kind.Property => propWithValue(
"KEY"),
139 var value = kind
switch {
140 Kind.Property or Kind.Value => propWithValue(
"VALUE"),
147 while(i < infoOutput.Count)
149 line = infoOutput[i];
150 if (!IsWithinCurrentItem(line, indent))
break;
151 if (!IsItemLine(line))
156 var item = Parse(ref infoOutput, ref i);
157 if (item.Key ==
null)
158 result._unnamedItems.Add(item);
160 result._namedItems.Add(item.Key!, item);
171 var infoOutput = toolOutput
172 .Where(o => o.Type == OutputType.Std)
173 .Select(o => o.Text.TrimEnd())
176 int i = infoOutput.FindIndex(0, IsItemLine);
179 while(i < infoOutput.Count)
181 line = infoOutput[i];
182 if (!IsItemLine(line))
187 var item = Parse(ref infoOutput, ref i);
188 if (item.Key ==
null)
189 result._unnamedItems.Add(item);
191 result._namedItems.Add(item.Key!, item);