Skip to content

Commit b6bcd08

Browse files
committed
Simplify SerializeTable in ConsoleLuaLibrary
1 parent f3799fb commit b6bcd08

File tree

2 files changed

+31
-17
lines changed

2 files changed

+31
-17
lines changed

src/BizHawk.Client.EmuHawk/tools/Lua/Libraries/ConsoleLuaLibrary.cs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Generic;
12
using System.Linq;
23
using System.Text;
34

@@ -66,23 +67,9 @@ private void LogWithSeparator(string separator, string terminator, params object
6667
{
6768
static string SerializeTable(LuaTable lti)
6869
{
69-
var keyObjs = lti.Keys;
70-
var valueObjs = lti.Values;
71-
if (keyObjs.Count != valueObjs.Count)
72-
{
73-
throw new ArgumentException(message: "each value must be paired with one key, they differ in number", paramName: nameof(lti));
74-
}
75-
76-
var values = new object[keyObjs.Count];
77-
var kvpIndex = 0;
78-
foreach (var valueObj in valueObjs)
79-
{
80-
values[kvpIndex++] = valueObj;
81-
}
82-
83-
return string.Concat(keyObjs.Cast<object>()
84-
.Select((kObj, i) => $"\"{kObj}\": \"{values[i]}\"\n")
85-
.Order());
70+
var entries = ((IEnumerator<KeyValuePair<object, object/*?*/>>) lti.GetEnumerator()).AsEnumerable()
71+
.ToArray();
72+
return string.Concat(entries.Select(static kvp => $"\"{kvp.Key}\": \"{kvp.Value}\"\n").Order());
8673
}
8774

8875
if (!Tools.Has<LuaConsole>())

src/BizHawk.Common/Extensions/CollectionExtensions.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,30 @@ namespace BizHawk.Common.CollectionExtensions
1010
public static class CollectionExtensions
1111
#pragma warning restore MA0104
1212
{
13+
private struct EnumeratorAsEnumerable<T> : IEnumerable<T>
14+
{
15+
private IEnumerator<T>? _wrapped;
16+
17+
public EnumeratorAsEnumerable(IEnumerator<T> wrapped)
18+
=> _wrapped = wrapped;
19+
20+
public override bool Equals(object? other)
21+
=> other is EnumeratorAsEnumerable<T> wrapper && object.Equals(_wrapped, wrapper._wrapped);
22+
23+
public IEnumerator<T> GetEnumerator()
24+
{
25+
var temp = _wrapped ?? throw new InvalidOperationException("double enumeration (or `default`/zeroed struct)");
26+
_wrapped = null;
27+
return temp;
28+
}
29+
30+
IEnumerator IEnumerable.GetEnumerator()
31+
=> GetEnumerator();
32+
33+
public override int GetHashCode()
34+
=> _wrapped?.GetHashCode() ?? default;
35+
}
36+
1337
private const string ERR_MSG_IMMUTABLE_LIST = "immutable list passed to mutating method";
1438

1539
private const string WARN_NONGENERIC = "use generic overload";
@@ -119,6 +143,9 @@ public static void AddRange<T>(this ICollection<T> list, IEnumerable<T> collecti
119143
foreach (var item in collection) list.Add(item);
120144
}
121145

146+
public static IEnumerable<T> AsEnumerable<T>(this IEnumerator<T> enumerator)
147+
=> new EnumeratorAsEnumerable<T>(enumerator);
148+
122149
/// <remarks>
123150
/// Contains method for arrays which does not need Linq, but rather uses Array.IndexOf
124151
/// similar to <see cref="ICollection{T}.Contains">ICollection's Contains</see>

0 commit comments

Comments
 (0)