Skip to content

Commit

Permalink
Fix throws exception when enum has same value #32
Browse files Browse the repository at this point in the history
  • Loading branch information
neuecc committed Jan 14, 2021
1 parent 1c80aa4 commit f618dee
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 8 deletions.
19 changes: 15 additions & 4 deletions src/ZString.Unity/Assets/Scripts/ZString/EnumUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace Cysharp.Text
{
internal static class EnumUtil<T>
{
const string InvalidName = "$";

static readonly Dictionary<T, string> names;
static readonly Dictionary<T, byte[]> utf8names;

Expand All @@ -18,14 +20,23 @@ static EnumUtil()
utf8names = new Dictionary<T, byte[]>(enumNames.Length);
for (int i = 0; i < enumNames.Length; i++)
{
names.Add((T)values.GetValue(i), enumNames[i]);
utf8names.Add((T)values.GetValue(i), Encoding.UTF8.GetBytes(enumNames[i]));
if (names.ContainsKey((T)values.GetValue(i)))
{
// already registered = invalid.
names[(T)values.GetValue(i)] = InvalidName;
utf8names[(T)values.GetValue(i)] = Array.Empty<byte>(); // byte[0] == Invalid.
}
else
{
names.Add((T)values.GetValue(i), enumNames[i]);
utf8names.Add((T)values.GetValue(i), Encoding.UTF8.GetBytes(enumNames[i]));
}
}
}

public static bool TryFormatUtf16(T value, Span<char> dest, out int written, ReadOnlySpan<char> _)
{
if (!names.TryGetValue(value, out var v))
if (!names.TryGetValue(value, out var v) || v == InvalidName)
{
v = value.ToString();
}
Expand All @@ -36,7 +47,7 @@ public static bool TryFormatUtf16(T value, Span<char> dest, out int written, Rea

public static bool TryFormatUtf8(T value, Span<byte> dest, out int written, StandardFormat _)
{
if (!utf8names.TryGetValue(value, out var v))
if (!utf8names.TryGetValue(value, out var v) || v.Length == 0)
{
v = Encoding.UTF8.GetBytes(value.ToString());
}
Expand Down
19 changes: 15 additions & 4 deletions src/ZString/EnumUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace Cysharp.Text
{
internal static class EnumUtil<T>
{
const string InvalidName = "$";

static readonly Dictionary<T, string> names;
static readonly Dictionary<T, byte[]> utf8names;

Expand All @@ -18,14 +20,23 @@ static EnumUtil()
utf8names = new Dictionary<T, byte[]>(enumNames.Length);
for (int i = 0; i < enumNames.Length; i++)
{
names.Add((T)values.GetValue(i), enumNames[i]);
utf8names.Add((T)values.GetValue(i), Encoding.UTF8.GetBytes(enumNames[i]));
if (names.ContainsKey((T)values.GetValue(i)))
{
// already registered = invalid.
names[(T)values.GetValue(i)] = InvalidName;
utf8names[(T)values.GetValue(i)] = Array.Empty<byte>(); // byte[0] == Invalid.
}
else
{
names.Add((T)values.GetValue(i), enumNames[i]);
utf8names.Add((T)values.GetValue(i), Encoding.UTF8.GetBytes(enumNames[i]));
}
}
}

public static bool TryFormatUtf16(T value, Span<char> dest, out int written, ReadOnlySpan<char> _)
{
if (!names.TryGetValue(value, out var v))
if (!names.TryGetValue(value, out var v) || v == InvalidName)
{
v = value.ToString();
}
Expand All @@ -36,7 +47,7 @@ public static bool TryFormatUtf16(T value, Span<char> dest, out int written, Rea

public static bool TryFormatUtf8(T value, Span<byte> dest, out int written, StandardFormat _)
{
if (!utf8names.TryGetValue(value, out var v))
if (!utf8names.TryGetValue(value, out var v) || v.Length == 0)
{
v = Encoding.UTF8.GetBytes(value.ToString());
}
Expand Down
78 changes: 78 additions & 0 deletions tests/ZString.Tests/EnumTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using Cysharp.Text;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Text;
using Xunit;

namespace ZStringTests
{
public enum DuplicateEnum
{
A = 1,
B = 2,
BB = 2,
C = 3
}

public enum StandardEnum
{
Abc = 1,
Def = 2,
Ghi = 3,
}

[Flags]
public enum FlagsEnum
{
None = 0,
Abc = 1,
Bcd = 2,
Efg = 4,
}

public class EnumTest
{
[Fact]
public void Duplicate()
{
ZString.Format("{0}", DuplicateEnum.A).Should().Be("A");
ZString.Format("{0}", DuplicateEnum.B).Should().Be("B");
ZString.Format("{0}", DuplicateEnum.BB).Should().Be("B");
ZString.Format("{0}", DuplicateEnum.C).Should().Be("C");
Utf8(DuplicateEnum.A);
Utf8(DuplicateEnum.B);
Utf8(DuplicateEnum.BB);
Utf8(DuplicateEnum.C);
}

[Fact]
public void Standard()
{
ZString.Format("{0}", StandardEnum.Abc).Should().Be("Abc");
ZString.Format("{0}", StandardEnum.Def).Should().Be("Def");
ZString.Format("{0}", StandardEnum.Ghi).Should().Be("Ghi");
Utf8(StandardEnum.Abc);
Utf8(StandardEnum.Def);
Utf8(StandardEnum.Ghi);
}

[Fact]
public void Flags()
{
ZString.Format("{0}", FlagsEnum.Abc | FlagsEnum.Bcd).Should().Be("Abc, Bcd");
ZString.Format("{0}", FlagsEnum.None).Should().Be("None");
ZString.Format("{0}", FlagsEnum.Efg).Should().Be("Efg");
Utf8(FlagsEnum.Abc | FlagsEnum.Bcd);
Utf8(FlagsEnum.None);
Utf8(FlagsEnum.Efg);
}

static void Utf8<T>(T e) where T : Enum
{
var s = ZString.CreateUtf8StringBuilder();
s.AppendFormat("{0}", e);
s.AsSpan().SequenceEqual(Encoding.UTF8.GetBytes(e.ToString())).Should().BeTrue();
}
}
}

0 comments on commit f618dee

Please sign in to comment.