Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/naming strategy #14

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 76 additions & 14 deletions OneBot-Interface/Core/Util/StringUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,34 @@ public enum CamelCaseType
{
Upper,

Lower
Lower,

None,
}

public enum CaseType
{
Lower,

Upper
Upper,

None,
}

private static CaseType EvaluateCaseType(char c)
{
if (char.IsUpper(c))
{
return CaseType.Upper;
}

if (char.IsLower(c))
{
return CaseType.Lower;
}

return CaseType.None;
}

public static bool IsNullOrEmpty(string? value)
=> string.IsNullOrEmpty(value);
Expand Down Expand Up @@ -80,9 +98,17 @@ public static string ToCamelCase(string s, CamelCaseType caseType, string[]? loc
char[] result = new char[src.Length - ulCnt];
bool fstWord = true, fstLetter = true;
string tmp = "";
var lastCase = CaseType.None;

for (int i = 0, j = 0; i <= src.Length; i++)
{
if (i == src.Length || src[i] == Underline || src[i] == Dash || char.IsSeparator(src[i]))
var cntCase = i < src.Length ? EvaluateCaseType(src[i]) : CaseType.None;

if (i == src.Length ||
src[i] == Underline || src[i] == Dash ||
char.IsSeparator(src[i]) ||
(i > 0 && lastCase != cntCase && cntCase == CaseType.Upper)
)
{
if (lockedWords != null && lockedWords.Contains(tmp))
{
Expand All @@ -95,13 +121,21 @@ public static string ToCamelCase(string s, CamelCaseType caseType, string[]? loc
result[j - tmp.Length + k] = char.ToLower(result[j - tmp.Length + k]);
}
}

if (i < src.Length)
{
if (src[i] == Underline || src[i] == Dash)
{
fstLetter = true;
tmp = "";
}
else if (i > 0 && lastCase != cntCase && cntCase == CaseType.Upper)
{
fstLetter = false;
result[j] = char.ToUpper(src[i]);
tmp = "" + char.ToUpper(src[i]);
j++;
}
else
{
fstWord = true;
Expand All @@ -126,11 +160,19 @@ public static string ToCamelCase(string s, CamelCaseType caseType, string[]? loc
}
else
{
if (j != 1 && lastCase == CaseType.Upper && cntCase == CaseType.Lower)
{
result[j - 1] = char.ToUpper(result[j - 1]);
}

result[j] = char.ToLower(src[i]);
}

tmp += char.ToUpper(src[i]);
j++;
}

lastCase = cntCase;
}

return new string(result);
Expand Down Expand Up @@ -164,20 +206,33 @@ public static string ToUpperSnakeCase(string s, string[]? lockedWords = null)
/// <returns></returns>
public static string ToSeparatedCase(string s, char separator, CaseType caseType, string[]? lockedWords = null)
{
StringBuilder sb = new StringBuilder();
StringBuilder sb = new StringBuilder(16);
char[] src = s.ToCharArray();

bool fstWord = true;
for (int i = 0; i < src.Length; i++)
int t = 0;
var separated = false;
var lastCase = CaseType.None;

for (int i = 0; i < src.Length; i++, t++)
{
var cntCase = i < src.Length ? EvaluateCaseType(src[i]) : CaseType.None;

if (char.IsSeparator(src[i]))
{
sb.Append(src[i]);
fstWord = true;
t = -1;
continue;
}
if (char.IsUpper(src[i]))

if (src[i] == Dash || src[i] == Underline)
{
separated = true;
continue;
}

if (separated || (lastCase != cntCase && cntCase == CaseType.Upper))
{
separated = false;
if (lockedWords != null)
{
bool skip = false;
Expand All @@ -192,12 +247,11 @@ public static string ToSeparatedCase(string s, char separator, CaseType caseType
break;
}
}

if (match)
{
if (!fstWord)
if (t != 0)
sb.Append(separator);
else
fstWord = false;
for (int k = 0; k < word.Length; k++)
{
if (caseType == CaseType.Upper)
Expand All @@ -206,23 +260,31 @@ public static string ToSeparatedCase(string s, char separator, CaseType caseType
sb.Append(char.ToLower(src[i]));
i++;
}

i--;
skip = true;
break;
}
}

if (skip)
continue;
}
if (!fstWord)

if (t != 0)
sb.Append(separator);
else
fstWord = false;
}

if (caseType == CaseType.Upper)
{
sb.Append(char.ToUpper(src[i]));
}
else
{
sb.Append(char.ToLower(src[i]));
}

lastCase = cntCase;
}

return sb.ToString();
Expand Down
76 changes: 57 additions & 19 deletions OneBot-UnitTest/UnitTest/Util/StringUtilsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,75 @@ public void ToSnakeCaseTest()
Assert.AreEqual("qq", lowerSnake.Convert("QQ"));
Assert.AreEqual("id", lowerSnake.Convert("ID"));
Assert.AreEqual("qq id", lowerSnake.Convert("QQ ID"));

Assert.AreEqual("qq_qq_id qq_id_id_qq", StringUtils.ToSnakeCase("QQQQID QQIDIDQQ", StringUtils.CaseType.Lower, lockedWords));
Assert.AreEqual("user_qq_token", StringUtils.ToSnakeCase("UserQQToken", StringUtils.CaseType.Lower, lockedWords));
Assert.AreEqual("sweet_icelolly_id", StringUtils.ToSnakeCase("SweetIcelollyID", StringUtils.CaseType.Lower, lockedWords));

// ambiguous case
// Assert.AreEqual("qq_qq_id qq_id_id_qq", StringUtils.ToSnakeCase("QQQQID QQIDIDQQ", StringUtils.CaseType.Lower, lockedWords));

Assert.AreEqual("user_qq_token",
StringUtils.ToSnakeCase("UserQQToken", StringUtils.CaseType.Lower, lockedWords));
Assert.AreEqual("sweet_icelolly_id",
StringUtils.ToSnakeCase("SweetIcelollyID", StringUtils.CaseType.Lower, lockedWords));
Assert.AreEqual("wey_sun+ice_eric_vancheng_dresses",
StringUtils.ToSnakeCase("WeySun+IceEricVanChengDresses", StringUtils.CaseType.Lower, new[] { "SUN+ICE", "VANCHENG" }));
StringUtils.ToSnakeCase("WeySun+IceEricVanChengDresses", StringUtils.CaseType.Lower,
new[] { "SUN+ICE", "VANCHENG" }));

Assert.AreEqual("QQ", StringUtils.ToSnakeCase("QQ", StringUtils.CaseType.Upper, lockedWords));
Assert.AreEqual("ID", StringUtils.ToSnakeCase("ID", StringUtils.CaseType.Upper, lockedWords));
Assert.AreEqual("QQ ID", StringUtils.ToSnakeCase("QQ ID", StringUtils.CaseType.Upper, lockedWords));
Assert.AreEqual("QQ_QQ_ID QQ_ID_ID_QQ", StringUtils.ToSnakeCase("QQQQID QQIDIDQQ", StringUtils.CaseType.Upper, lockedWords));
Assert.AreEqual("USER_QQ_TOKEN", StringUtils.ToSnakeCase("UserQQToken", StringUtils.CaseType.Upper, lockedWords));
Assert.AreEqual("SWEET_ICELOLLY_ID", StringUtils.ToSnakeCase("SweetIcelollyID", StringUtils.CaseType.Upper, lockedWords));
Assert.AreEqual("QQ_QQ_ID QQ_ID_ID_QQ",
StringUtils.ToSnakeCase("QQQQID QQIDIDQQ", StringUtils.CaseType.Upper, lockedWords));
Assert.AreEqual("USER_QQ_TOKEN",
StringUtils.ToSnakeCase("UserQQToken", StringUtils.CaseType.Upper, lockedWords));
Assert.AreEqual("SWEET_ICELOLLY_ID",
StringUtils.ToSnakeCase("SweetIcelollyID", StringUtils.CaseType.Upper, lockedWords));
Assert.AreEqual("WEY_SUN+ICE_ERIC_VANCHENG_DRESSES",
StringUtils.ToSnakeCase("WeySun+IceEricVanChengDresses", StringUtils.CaseType.Upper, new[] { "SUN+ICE", "VANCHENG" }));
StringUtils.ToSnakeCase("WeySun+IceEricVanChengDresses", StringUtils.CaseType.Upper,
new[] { "SUN+ICE", "VANCHENG" }));

Assert.AreEqual("one_another", StringUtils.ToSnakeCase("oneAnother", StringUtils.CaseType.Lower, lockedWords));
Assert.AreEqual("ONE_ANOTHER", StringUtils.ToSnakeCase("oneAnother", StringUtils.CaseType.Upper, lockedWords));

Assert.AreEqual("ONE_ANOTHER", StringUtils.ToSnakeCase("one-Another", StringUtils.CaseType.Upper, lockedWords));
Assert.AreEqual("ONE_ANOTHER", StringUtils.ToSnakeCase("one_Another", StringUtils.CaseType.Upper, lockedWords));
Assert.AreEqual("ONE_ANOTHER",
StringUtils.ToSnakeCase("one_-Another", StringUtils.CaseType.Upper, lockedWords));
Assert.AreEqual("ONE_ANOTHER", StringUtils.ToSnakeCase("ONE_ANOTHER", StringUtils.CaseType.Upper, lockedWords));
}

[TestMethod]
public void ToLowerCamelTest()
{
Assert.AreEqual("userQQ", StringUtils.ToCamelCase("USER_QQ", StringUtils.CamelCaseType.Lower, lockedWords));

Assert.AreEqual("userQQ", StringUtils.ToCamelCase("user_qq", StringUtils.CamelCaseType.Lower, lockedWords));
Assert.AreEqual("userQQ", StringUtils.ToCamelCase("userQQ", StringUtils.CamelCaseType.Lower, lockedWords));
Assert.AreEqual("userQQ", StringUtils.ToCamelCase("USER_QQ", StringUtils.CamelCaseType.Lower, lockedWords));
Assert.AreEqual("userQQ", StringUtils.ToCamelCase("userQq", StringUtils.CamelCaseType.Lower, lockedWords));
Assert.AreEqual("userID", StringUtils.ToCamelCase("user_id", StringUtils.CamelCaseType.Lower, lockedWords));
Assert.AreEqual("qqID", StringUtils.ToCamelCase("qq_id", StringUtils.CamelCaseType.Lower, lockedWords));
Assert.AreEqual("icelolly", StringUtils.ToCamelCase("icelolly", StringUtils.CamelCaseType.Lower));
Assert.AreEqual("icelolly", StringUtils.ToCamelCase("Icelolly", StringUtils.CamelCaseType.Lower));
Assert.AreEqual("icelolly", StringUtils.ToCamelCase("IceLOlly", StringUtils.CamelCaseType.Lower));

// ambiguous case
Assert.AreEqual("iceLOlly", StringUtils.ToCamelCase("IceLOlly", StringUtils.CamelCaseType.Lower));

Assert.AreEqual("icelollyDress", StringUtils.ToCamelCase("icelolly_dress", StringUtils.CamelCaseType.Lower));
Assert.AreEqual("icelollyDress2", StringUtils.ToCamelCase("icelolly_dress2", StringUtils.CamelCaseType.Lower));
Assert.AreEqual("icelollyDress", StringUtils.ToCamelCase("ICelolly_DRess", StringUtils.CamelCaseType.Lower));
Assert.AreEqual("icelollyDress daiSuki", StringUtils.ToCamelCase("iCelolly_dRess dai_suki", StringUtils.CamelCaseType.Lower));
Assert.AreEqual("icelollyDress daiSuki404", StringUtils.ToCamelCase("iCelolly_dRess dai_suki_404", StringUtils.CamelCaseType.Lower));
Assert.AreEqual("icelollyDress2", StringUtils.ToCamelCase("icelolly_dress_2", StringUtils.CamelCaseType.Lower));

Assert.AreEqual("aDRess", StringUtils.ToCamelCase("A_DRess", StringUtils.CamelCaseType.Lower));

// ambiguous case
Assert.AreEqual("iCelollyDRess", StringUtils.ToCamelCase("ICelolly_DRess", StringUtils.CamelCaseType.Lower));

Assert.AreEqual("iCelollyDRess daiSuki",
StringUtils.ToCamelCase("iCelolly_dRess dai_suki", StringUtils.CamelCaseType.Lower));
Assert.AreEqual("iCelollyDRess daiSuki404",
StringUtils.ToCamelCase("iCelolly_dRess dai_suki_404", StringUtils.CamelCaseType.Lower));
Assert.AreEqual("iCelollyDRess",
StringUtils.ToCamelCase("iCelolly_----dRess", StringUtils.CamelCaseType.Lower));
}

[TestMethod]
public void ToUpperCamelTest()
{
Expand All @@ -62,11 +98,13 @@ public void ToUpperCamelTest()
Assert.AreEqual("QQID", StringUtils.ToCamelCase("qq_id", StringUtils.CamelCaseType.Upper, lockedWords));
Assert.AreEqual("Icelolly", StringUtils.ToCamelCase("icelolly", StringUtils.CamelCaseType.Upper));
Assert.AreEqual("Icelolly", StringUtils.ToCamelCase("Icelolly", StringUtils.CamelCaseType.Upper));
Assert.AreEqual("Icelolly", StringUtils.ToCamelCase("IceLOlly", StringUtils.CamelCaseType.Upper));
Assert.AreEqual("IceLOlly", StringUtils.ToCamelCase("IceLOlly", StringUtils.CamelCaseType.Upper));
Assert.AreEqual("IcelollyDress", StringUtils.ToCamelCase("icelolly_dress", StringUtils.CamelCaseType.Upper));
Assert.AreEqual("IcelollyDress2", StringUtils.ToCamelCase("icelolly_dress2", StringUtils.CamelCaseType.Upper));
Assert.AreEqual("IcelollyDress", StringUtils.ToCamelCase("ICelolly_DRess", StringUtils.CamelCaseType.Upper));
Assert.AreEqual("IcelollyDress DaiSuki", StringUtils.ToCamelCase("iCelolly_dRess dai_suki", StringUtils.CamelCaseType.Upper));
Assert.AreEqual("IcelollyDress DaiSuki404", StringUtils.ToCamelCase("iCelolly_dRess dai_suki_404", StringUtils.CamelCaseType.Upper));
Assert.AreEqual("ICelollyDRess", StringUtils.ToCamelCase("ICelolly_DRess", StringUtils.CamelCaseType.Upper));
Assert.AreEqual("ICelollyDRess DaiSuki",
StringUtils.ToCamelCase("iCelolly_dRess dai_suki", StringUtils.CamelCaseType.Upper));
Assert.AreEqual("ICelollyDRess DaiSuki404",
StringUtils.ToCamelCase("iCelolly_dRess dai_suki_404", StringUtils.CamelCaseType.Upper));
}
}