< Summary

Information
Line coverage
100%
Covered lines: 38
Uncovered lines: 0
Coverable lines: 38
Total lines: 128
Line coverage: 100%
Branch coverage
100%
Covered branches: 20
Total branches: 20
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
GetLocalizedEnums(...)100%66100%
GetLocalizedSmartEnums(...)100%66100%
GetLocalizedEnums(...)100%22100%
GetLocalizedSmartEnums(...)100%22100%
ValidateExcludedValues(...)100%44100%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Observable/Extensions/EnumExtensions/EnumExtensions.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="EnumExtensions.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Collections.Generic;
 9using System.Globalization;
 10using System.Linq;
 11using MyNet.Primitives;
 12
 13#pragma warning disable IDE0130 // Namespace does not match folder structure
 14namespace MyNet.Observable;
 15#pragma warning restore IDE0130 // Namespace does not match folder structure
 16
 17/// <summary>
 18/// Builds localized item lists for system enums and smart enums.
 19/// </summary>
 20public static class EnumExtensions
 21{
 22    extension(Type type)
 23    {
 24        /// <summary>
 25        /// Creates a list of <see cref="LocalizedEnum"/> values for a system enum type.
 26        /// </summary>
 27        /// <param name="excludedValues">Optional enum values to exclude from the result.</param>
 28        /// <returns>A localized item for each enum member.</returns>
 29        public IList<LocalizedEnum> GetLocalizedEnums(IEnumerable<object>? excludedValues = null)
 30        {
 1831            ArgumentNullException.ThrowIfNull(type);
 32
 1533            if (!type.IsEnum)
 34            {
 335                throw new ArgumentException($"Type '{type.FullName}' is not a system enum.");
 36            }
 37
 1238            var excludedList = excludedValues?.ToList();
 1239            if (excludedList is not null)
 40            {
 641                ValidateExcludedValues(type, excludedList);
 42            }
 43
 944            return [.. Enum.GetValues(type)
 945                .Cast<Enum>()
 946                .Where(x => excludedList?.Contains(x) != true)
 947                .Select(x => new LocalizedEnum(x))];
 48        }
 49
 50        /// <summary>
 51        /// Creates a list of <see cref="LocalizedSmartEnum"/> values for a smart enum type.
 52        /// </summary>
 53        /// <param name="excludedValues">Optional smart enum values to exclude from the result.</param>
 54        /// <returns>A localized item for each smart enum member.</returns>
 55        public IList<LocalizedSmartEnum> GetLocalizedSmartEnums(IEnumerable<object>? excludedValues = null)
 56        {
 1257            ArgumentNullException.ThrowIfNull(type);
 58
 1259            if (!typeof(ISmartEnum).IsAssignableFrom(type))
 60            {
 361                throw new ArgumentException(
 362                    $"Type '{type.FullName}' does not implement {nameof(ISmartEnum)}.");
 63            }
 64
 965            var excludedList = excludedValues?.ToList();
 966            if (excludedList is not null)
 67            {
 668                ValidateExcludedValues(type, excludedList);
 69            }
 70
 671            return [.. SmartEnumSource.GetAll(type)
 672                .Where(x => excludedList?.Contains(x) != true)
 673                .Select(x => new LocalizedSmartEnum(x))];
 74        }
 75    }
 76
 77    /// <summary>
 78    /// Creates a list of <see cref="LocalizedEnum{TEnum}"/> values for a system enum type.
 79    /// </summary>
 80    /// <typeparam name="TEnum">The enum type.</typeparam>
 81    /// <param name="excludedValues">Optional enum values to exclude from the result.</param>
 82    /// <returns>A localized item for each enum member.</returns>
 83    public static IList<LocalizedEnum<TEnum>> GetLocalizedEnums<TEnum>(IEnumerable<TEnum>? excludedValues = null)
 84        where TEnum : struct, Enum
 685        => [.. Enum.GetValues<TEnum>()
 686            .Where(x => excludedValues?.Contains(x) != true)
 687            .Select(x => new LocalizedEnum<TEnum>(x))];
 88
 89    /// <summary>
 90    /// Creates a list of <see cref="LocalizedSmartEnum{TSmartEnum}"/> values for a smart enum type.
 91    /// </summary>
 92    /// <typeparam name="TSmartEnum">The smart enum type.</typeparam>
 93    /// <param name="excludedValues">Optional smart enum values to exclude from the result.</param>
 94    /// <returns>A localized item for each smart enum member.</returns>
 95    public static IList<LocalizedSmartEnum<TSmartEnum>> GetLocalizedSmartEnums<TSmartEnum>(
 96        IEnumerable<TSmartEnum>? excludedValues = null)
 97        where TSmartEnum : class, ISmartEnum
 698        => [.. SmartEnumSource.GetAll<TSmartEnum>()
 699            .Where(x => excludedValues?.Contains(x) != true)
 6100            .Select(x => new LocalizedSmartEnum<TSmartEnum>(x))];
 101
 102    /// <summary>
 103    /// Validates excluded values against the expected enum or smart enum type.
 104    /// </summary>
 105    /// <param name="enumType">The enum or smart enum type.</param>
 106    /// <param name="excludedValues">The values to validate.</param>
 107    /// <exception cref="ArgumentNullException">Thrown when an argument is null.</exception>
 108    /// <exception cref="ArgumentException">Thrown when an excluded value has an invalid type.</exception>
 109    private static void ValidateExcludedValues(Type enumType, IEnumerable<object> excludedValues)
 110    {
 12111        ArgumentNullException.ThrowIfNull(enumType);
 12112        ArgumentNullException.ThrowIfNull(excludedValues);
 113
 12114        var invalidType = enumType.IsEnum
 12115            ? excludedValues
 12116                .Select(v => Nullable.GetUnderlyingType(v.GetType()) ?? v.GetType())
 12117                .FirstOrDefault(e => !e.IsEnum || e != enumType)
 12118            : excludedValues
 12119                .Select(v => v.GetType())
 12120                .FirstOrDefault(e => e != enumType && !enumType.IsAssignableFrom(e));
 121
 12122        if (invalidType != null)
 123        {
 6124            throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Wrong type : {0}", invalidType.Name
 125        }
 6126    }
 127}
 128