< Summary

Information
Class: ArturRios.Extensions.StringExtensions
Assembly: ArturRios.Extensions
File(s): D:\Repositories\dotnet-extensions\src\StringExtensions.cs
Line coverage
100%
Covered lines: 22
Uncovered lines: 0
Coverable lines: 22
Total lines: 145
Line coverage: 100%
Branch coverage
100%
Covered branches: 14
Total branches: 14
Branch coverage: 100%
Method coverage
100%
Covered methods: 14
Fully covered methods: 13
Total methods: 14
Method coverage: 100%
Full method coverage: 92.8%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
IsValidEnumValue(...)100%11100%
ValueOrDefault(...)100%22100%
JoinWith(...)100%11100%
JoinWith(...)100%44100%
HasLowerChar(...)100%11100%
HasMaxLength(...)100%11100%
HasMinLength(...)100%11100%
HasNumber(...)100%11100%
HasUpperChar(...)100%11100%
IsValidEmail(...)100%11100%
TrimChar(...)100%22100%
ParseToBoolOrDefault(...)100%22100%
ParseToIntOrDefault(...)100%22100%
ParseToObjectOrDefault(...)100%22100%

File(s)

D:\Repositories\dotnet-extensions\src\StringExtensions.cs

#LineLine coverage
 1using System.Text.Json;
 2using ArturRios.Util.RegularExpressions;
 3
 4namespace ArturRios.Extensions;
 5
 6/// <summary>
 7///     Provides extension methods for working with strings, including validation helpers,
 8///     parsing utilities, and convenient join operations.
 9/// </summary>
 10public static class StringExtensions
 11{
 12    /// <summary>
 13    ///     Checks if the string corresponds to a valid value of the specified enum type.
 14    /// </summary>
 15    /// <typeparam name="TEnum">The enum type to validate against.</typeparam>
 16    /// <param name="string">Input string value.</param>
 17    /// <param name="ignoreCase">Whether to ignore case during parsing (default true).</param>
 18    /// <returns>True if the string can be parsed to the enum; otherwise false.</returns>
 19    public static bool IsValidEnumValue<TEnum>(this string @string, bool ignoreCase = true) where TEnum : Enum =>
 520        Enum.TryParse(typeof(TEnum), @string, ignoreCase, out _);
 21
 22    /// <summary>
 23    ///     Returns the string if it has value; otherwise returns the provided default.
 24    /// </summary>
 25    /// <param name="string">The input string.</param>
 26    /// <param name="defaultValue">Default value when input is null or empty.</param>
 27    /// <returns>The input string or the default value.</returns>
 28    public static string? ValueOrDefault(this string? @string, string? defaultValue = null) =>
 329        string.IsNullOrEmpty(@string) ? defaultValue : @string;
 30
 31    /// <summary>
 32    ///     Joins the sequence of strings using the provided separator.
 33    /// </summary>
 34    /// <param name="source">The sequence of strings to join.</param>
 35    /// <param name="separator">Separator to use (default ", ").</param>
 36    /// <returns>A single concatenated string.</returns>
 37    public static string JoinWith(this IEnumerable<string> source, string separator = ", ") =>
 238        string.Join(separator, source);
 39
 40    /// <summary>
 41    ///     Joins the sequence of items using the provided separator, converting each to string.
 42    /// </summary>
 43    /// <typeparam name="T">Item type.</typeparam>
 44    /// <param name="source">The sequence to join.</param>
 45    /// <param name="separator">Separator to use (default ", ").</param>
 46    /// <returns>A single concatenated string.</returns>
 47    public static string JoinWith<T>(this IEnumerable<T> source, string separator = ", ") =>
 748        string.Join(separator, source.Select(x => x?.ToString()));
 49
 50    /// <summary>
 51    ///     Provides validation helpers for the given non-null string.
 52    /// </summary>
 53    extension(string @string)
 54    {
 55        /// <summary>
 56        ///     Checks whether the string contains at least one lowercase character.
 57        /// </summary>
 58        /// <returns>True if the string has a lowercase character; otherwise false.</returns>
 559        public bool HasLowerChar() => RegexCollection.HasLowerChar().IsMatch(@string);
 60
 61        /// <summary>
 62        ///     Checks whether the string length is less than or equal to the given maximum.
 63        /// </summary>
 64        /// <param name="maxLength">Maximum allowed length.</param>
 65        /// <returns>True if within the max length; otherwise false.</returns>
 466        public bool HasMaxLength(int maxLength) => !(@string.Length > maxLength);
 67
 68        /// <summary>
 69        ///     Checks whether the string length is greater than or equal to the given minimum.
 70        /// </summary>
 71        /// <param name="minLength">Minimum required length.</param>
 72        /// <returns>True if meets the min length; otherwise false.</returns>
 473        public bool HasMinLength(int minLength) => !(@string.Length < minLength);
 74
 75        /// <summary>
 76        ///     Checks whether the string contains at least one numeric character.
 77        /// </summary>
 78        /// <returns>True if a number is present; otherwise false.</returns>
 479        public bool HasNumber() => RegexCollection.HasNumber().IsMatch(@string);
 80
 81        /// <summary>
 82        ///     Checks whether the string contains at least one uppercase character.
 83        /// </summary>
 84        /// <returns>True if the string has an uppercase character; otherwise false.</returns>
 585        public bool HasUpperChar() => RegexCollection.HasUpperChar().IsMatch(@string);
 86
 87        /// <summary>
 88        ///     Validates whether the string matches a basic email format.
 89        /// </summary>
 90        /// <returns>True if the string is a valid email; otherwise false.</returns>
 591        public bool IsValidEmail() => RegexCollection.Email().IsMatch(@string);
 92
 93        /// <summary>
 94        ///     Trims leading/trailing whitespace and the specified character from the ends of the string.
 95        /// </summary>
 96        /// <param name="charToTrim">Character to trim from both ends.</param>
 97        /// <returns>The trimmed string.</returns>
 98        public string TrimChar(char charToTrim) =>
 499            string.IsNullOrEmpty(@string) ? @string : @string.Trim().Trim(charToTrim);
 100    }
 101
 102    /// <summary>
 103    ///     Provides parsing helpers for a nullable string.
 104    /// </summary>
 105    extension(string? @string)
 106    {
 107        /// <summary>
 108        ///     Parses the string to a boolean, or returns the provided default if parsing fails.
 109        /// </summary>
 110        /// <param name="defaultValue">Value to return when parsing fails.</param>
 111        /// <returns>The parsed boolean or the default value.</returns>
 112        public bool? ParseToBoolOrDefault(bool? defaultValue = null) =>
 6113            bool.TryParse(@string, out var result) ? result : defaultValue;
 114
 115        /// <summary>
 116        ///     Parses the string to an integer, or returns the provided default if parsing fails.
 117        /// </summary>
 118        /// <param name="defaultValue">Value to return when parsing fails.</param>
 119        /// <returns>The parsed integer or the default value.</returns>
 120        public int? ParseToIntOrDefault(int? defaultValue = null) =>
 4121            int.TryParse(@string, out var result) ? result : defaultValue;
 122
 123        /// <summary>
 124        ///     Attempts to deserialize the JSON string to an object of type <typeparamref name="T" />.
 125        /// </summary>
 126        /// <typeparam name="T">Target reference type.</typeparam>
 127        /// <returns>An instance of T if deserialization succeeds; otherwise null.</returns>
 128        public T? ParseToObjectOrDefault<T>() where T : class
 4129        {
 4130            if (string.IsNullOrEmpty(@string))
 2131            {
 2132                return null;
 133            }
 134
 135            try
 2136            {
 2137                return JsonSerializer.Deserialize<T>(@string);
 138            }
 1139            catch
 1140            {
 1141                return null;
 142            }
 143        }
 144    }
 145}