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

feat:replenish extensions #435

Merged
merged 13 commits into from
Feb 7, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public static class ObjectExtensions
}

//struct
return GetObjValue(type, obj, preStr, isEnumString, isCamelCase, isUrlEncode);
return GetObjValue(type, obj, preStr, isEnumString, isCamelCase, isUrlEncode);
}

if (type.IsArray || type.GetInterfaces().Any(t => t.Name.IndexOf("IEnumerable") == 0))
Expand All @@ -68,15 +68,15 @@ private static string GetObjValue(Type type, object obj, string preStr, bool isE

foreach (var item in properties)
{
var str = GetMemerInfoValue(item, item.GetValue(obj), preStr, isEnumString, isCamelCase, isUrlEncode);
var str = GetMemberInfoValue(item, item.GetValue(obj), preStr, isEnumString, isCamelCase, isUrlEncode);
if (string.IsNullOrEmpty(str))
continue;
list.Add(str);
}

foreach (var item in fields)
{
var str = GetMemerInfoValue(item, item.GetValue(obj), preStr, isEnumString, isCamelCase, isUrlEncode);
var str = GetMemberInfoValue(item, item.GetValue(obj), preStr, isEnumString, isCamelCase, isUrlEncode);
if (string.IsNullOrEmpty(str))
continue;
list.Add(str);
Expand All @@ -89,7 +89,7 @@ private static string GetObjValue(Type type, object obj, string preStr, bool isE
return string.Join('&', list);
}

private static string? GetMemerInfoValue(MemberInfo info, object? value, string preStr, bool isEnumString = false, bool isCamelCase = true, bool isUrlEncode = true)
private static string? GetMemberInfoValue(MemberInfo info, object? value, string preStr, bool isEnumString = false, bool isCamelCase = true, bool isUrlEncode = true)
{
if (value == null)
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace System.Collections;

public static class CollectionExtensions
{
public static bool IsNullOrEmpty<T>(this ICollection<T> source)
{
return source == null || !source.Any();
}

public static bool AddIfNotContains<T>(this ICollection<T> source, T item)
{
if (source.Contains(item))
{
return false;
}

source.Add(item);
return true;
}

public static void AddIfNotContains<T>(this ICollection<T> source, IEnumerable<T> items)
{
foreach (var item in items)
{
if (source.Contains(item))
{
continue;
}
source.Add(item);
}
}

public static int RemoveAll<T>(this ICollection<T> source, Func<T, bool> predicate)
{
var items = source.Where(predicate).ToList();
foreach (var item in items)
{
source.Remove(item);
}

return items.Count;
}

public static void RemoveAll<T>(this ICollection<T> source, IEnumerable<T> items)
{
foreach (var item in items)
{
source.Remove(item);
}
}
}
4 changes: 2 additions & 2 deletions src/Utils/Extensions/Masa.Utils.Extensions.DotNet/FillType.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) MASA Stack All rights reserved.
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

// ReSharper disable once CheckNamespace
Expand All @@ -7,7 +7,7 @@ namespace System;

public enum FillType
{
NoFile = 1,
NoFill = 1,

/// <summary>
/// left fill
Expand Down
241 changes: 238 additions & 3 deletions src/Utils/Extensions/Masa.Utils.Extensions.DotNet/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) MASA Stack All rights reserved.
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

// ReSharper disable once CheckNamespace
Expand Down Expand Up @@ -49,10 +49,10 @@ public static string GetSpecifiedLengthString(
this string value,
int length,
Action action,
FillType fillType = FillType.NoFile,
FillType fillType = FillType.NoFill,
char fillCharacter = ' ')
{
if (fillType == FillType.NoFile && value.Length < length)
if (fillType == FillType.NoFill && value.Length < length)
action.Invoke();

var keyLength = value.Length;
Expand All @@ -66,4 +66,239 @@ public static string GetSpecifiedLengthString(

throw new NotSupportedException($"... Unsupported {nameof(fillType)}");
}

/// <summary>
/// If the given string does not end with char, char is added to the end of the given string.
/// </summary>
public static string EnsureEndsWith(this string str, char c, StringComparison comparisonType = StringComparison.Ordinal)
{
if (str.EndsWith(c.ToString(), comparisonType))
{
return str;
}

return str + c;
}

/// <summary>
/// If the given string does not start with char, char is added to the beginning of the given string.
/// </summary>
public static string EnsureStartsWith(this string str, char c, StringComparison comparisonType = StringComparison.Ordinal)
{
if (str.StartsWith(c.ToString(), comparisonType))
{
return str;
}

return c + str;
}

/// <summary>
/// Converts new line const in the string to <see cref="Environment.NewLine"/>.
/// </summary>
public static string NormalizeLineBreak(this string str)
{
return str.Replace("\r\n", "\n").Replace("\r", "\n").Replace("\n", Environment.NewLine);
}

/// <summary>
/// Gets a substring of a string from beginning of the string.
/// </summary>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="str"/> is null</exception>
/// <exception cref="ArgumentException">Thrown if <paramref name="len"/> is bigger that string's length</exception>
public static string Left(this string str, int len)
{
if (str.Length < len)
{
throw new ArgumentException("len argument can`t be greater than string's length!");
}

return str.Substring(0, len);
}

/// <summary>
/// Gets a substring of a string from end of the string.
/// </summary>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="str"/> is null</exception>
/// <exception cref="ArgumentException">Thrown if <paramref name="len"/> is bigger that string's length</exception>
public static string Right(this string str, int len)
{
if (str.Length < len)
{
throw new ArgumentException("len argument can`t be greater than string's length!");
}

return str.Substring(str.Length - len, len);
}

/// <summary>
/// split string by <see cref="Environment.NewLine"/>.
/// </summary>
public static string[] SplitToLines(this string str)
{
return str.Split(Environment.NewLine);
}

/// <summary>
/// split string by <see cref="Environment.NewLine"/>.
/// </summary>
public static string[] SplitToLines(this string str, StringSplitOptions options)
{
return str.Split(Environment.NewLine, options);
}

public static string ToFirstCharUpper(this string str)
{
if (str.IsNullOrWhiteSpace())
{
return str;
}
return char.ToUpperInvariant(str[0]) + str.Substring(1);
}

public static string ToFirstCharLower(this string str)
{
if (str.IsNullOrWhiteSpace())
{
return str;
}
return char.ToLowerInvariant(str[0]) + str.Substring(1);
}

/// <summary>
/// Conversion string to PascalCase.
/// Example: User_Name -> UserName, user_name -> UserName, user_Name -> UserName, User_name -> UserName
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string ToPascalCase(this string str)
{
if (str.IsNullOrWhiteSpace())
{
return str;
}
return string.Join("", str.Split(new[] { '-', '_', ' ' })
.Where(s => !s.IsNullOrWhiteSpace())
.Select(c => ToFirstCharUpper(c)));
}

/// <summary>
/// Conversion string to CamelCase.
/// Example: User_Name -> userName, user_name -> userName, user_Name -> userName, User_name -> userName
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string ToCamelCase(this string str)
{
if (str.IsNullOrWhiteSpace())
{
return str;
}
return string.Join("", str.Split(new[] { '-', '_', ' ' })
.Where(s => !s.IsNullOrWhiteSpace())
.Select((c, i) => i == 0 ? ToFirstCharLower(c) : ToFirstCharUpper(c)));
}

/// <summary>
/// Conversion PascalCase/camelCase string to sentence (splitting words by space).
/// Example: "ThisIsSampleSentence" is converted to "This is sample sentence".
/// </summary>
/// <param name="str"></param>
public static string ToSentenceCase(this string str)
{
if (str.IsNullOrWhiteSpace())
{
return str;
}

return ToFirstCharUpper(ConvertCase(str, ' '));
}

/// <summary>
/// Conversion PascalCase/camelCase string to kebab-case.
/// Example: "UserName" is converted to "user-name".
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string ToKebabCase(this string str)
{
if (str.IsNullOrEmpty())
{
return str;
}
return ConvertCase(str, '-');
}

/// <summary>
/// conversion PascalCase/camelCase string to snake case.
/// Example: "UserName" is converted to "user_name".
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string ToSnakeCase(this string str)
{
if (str.IsNullOrWhiteSpace())
{
return str;
}

return ConvertCase(str, '_');
}

#pragma warning disable S3776
private static string ConvertCase(string str, char wordDelimiter)
{
var builder = new StringBuilder(str.Length + Math.Min(2, str.Length / 5));
var previousCategory = default(UnicodeCategory?);
for (var currentIndex = 0; currentIndex < str.Length; currentIndex++)
{
var currentChar = str[currentIndex];
if (currentChar == wordDelimiter)
{
builder.Append(wordDelimiter);
previousCategory = null;
continue;
}

var currentCategory = char.GetUnicodeCategory(currentChar);
switch (currentCategory)
{
case UnicodeCategory.UppercaseLetter:
case UnicodeCategory.TitlecaseLetter:
if (previousCategory == UnicodeCategory.SpaceSeparator ||
previousCategory == UnicodeCategory.LowercaseLetter ||
previousCategory != UnicodeCategory.DecimalDigitNumber &&
previousCategory != null &&
currentIndex > 0 &&
currentIndex + 1 < str.Length &&
char.IsLower(str[currentIndex + 1]))
{
builder.Append(wordDelimiter);
}

currentChar = char.ToLower(currentChar);
break;

case UnicodeCategory.LowercaseLetter:
case UnicodeCategory.DecimalDigitNumber:
if (previousCategory == UnicodeCategory.SpaceSeparator)
{
builder.Append(wordDelimiter);
}
break;

default:
if (previousCategory != null)
{
previousCategory = UnicodeCategory.SpaceSeparator;
}
continue;
}

builder.Append(currentChar);
previousCategory = currentCategory;
}
return builder.ToString();
}
#pragma warning restore S3776
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
global using System.Dynamic;
global using System.Globalization;
global using System.Reflection;
global using System.Runtime.CompilerServices;
global using System.Security.Cryptography;
global using System.Text;
global using System.Text.Json.Serialization;
global using System.Text.RegularExpressions;
Loading