< Summary

Information
Class: Allyaria.Theming.Helpers.ThemeNavigator
Assembly: Allyaria.Theming
File(s): /home/runner/work/allyaria/allyaria/src/Allyaria.Theming/Helpers/ThemeNavigator.cs
Line coverage
97%
Covered lines: 44
Uncovered lines: 1
Coverable lines: 45
Total lines: 138
Line coverage: 97.7%
Branch coverage
90%
Covered branches: 18
Total branches: 20
Branch coverage: 90%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_ComponentTypes()100%11100%
get_ThemeTypes()100%11100%
get_ComponentStates()100%11100%
get_StyleTypes()100%11100%
.cctor()100%11100%
BuildList(...)83.33%121285.71%
SetAllComponentStates()100%11100%
SetAllComponentTypes()100%11100%
SetAllStyleTypes()100%11100%
SetComponentStates(...)100%11100%
SetComponentTypes(...)100%11100%
SetContrastThemeTypes(...)100%22100%
SetStyleTypes(...)100%11100%
SetThemeType(...)100%66100%
SetThemeTypes(...)100%11100%

File(s)

/home/runner/work/allyaria/allyaria/src/Allyaria.Theming/Helpers/ThemeNavigator.cs

#LineLine coverage
 1namespace Allyaria.Theming.Helpers;
 2
 3/// <summary>
 4/// Represents a navigational context for resolving theming relationships across components, states, and style types in 
 5/// Allyaria theming engine.
 6/// </summary>
 7/// <remarks>
 8///     <para>
 9///     <see cref="ThemeNavigator" /> is used to describe combinations of component types, visual states, and theme
 10///     variations. It provides fluent methods for building specific navigation contexts for theme updates, typically
 11///     consumed by <see cref="ThemeUpdater" />.
 12///     </para>
 13///     <para>
 14///     The static <see cref="Initialize" /> member provides an empty baseline instance that can be progressively
 15///     specialized using the <c>Set*</c> methods.
 16///     </para>
 17/// </remarks>
 18public readonly record struct ThemeNavigator(
 1267219    IReadOnlyList<ComponentType> ComponentTypes,
 1261520    IReadOnlyList<ThemeType> ThemeTypes,
 1336921    IReadOnlyList<ComponentState> ComponentStates,
 2543422    IReadOnlyList<StyleType> StyleTypes
 23)
 24{
 25    /// <summary>
 26    /// Gets a base instance of <see cref="ThemeNavigator" /> with all internal lists initialized and empty.
 27    /// </summary>
 128    public static readonly ThemeNavigator Initialize = new(
 129        ComponentTypes: BuildList<ComponentType>(),
 130        ThemeTypes: BuildList<ThemeType>(),
 131        ComponentStates: BuildList<ComponentState>(),
 132        StyleTypes: BuildList<StyleType>()
 133    );
 34
 35    /// <summary>
 36    /// Builds a typed list of enum values, validating that the provided type is one of the supported theming enums (
 37    /// <see cref="ComponentType" />, <see cref="ThemeType" />, <see cref="ComponentState" />, or <see cref="StyleType" 
 38    /// </summary>
 39    /// <typeparam name="TEnum">The enum type to populate.</typeparam>
 40    /// <param name="items">The enum values to include in the list.</param>
 41    /// <returns>A new list containing the provided items, or an empty list if none were provided.</returns>
 42    /// <exception cref="AryArgumentException">Thrown if an unsupported enum type is used.</exception>
 43    private static List<TEnum> BuildList<TEnum>(params TEnum[] items)
 44        where TEnum : Enum
 45    {
 2600546        if (items.Length is 0)
 47        {
 548            return new List<TEnum>();
 49        }
 50
 2600051        if (!(items[0] is ComponentState or ComponentType or ThemeType or StyleType))
 52        {
 53            // Code Coverage: This is unreachable through all public methods.
 054            throw new AryArgumentException(message: "Invalid enum type", argName: nameof(items));
 55        }
 56
 2600057        var list = new List<TEnum>(capacity: items.Length);
 2600058        list.AddRange(collection: items);
 59
 2600060        return list;
 61    }
 62
 63    /// <summary>
 64    /// Sets all component states except <see cref="ComponentState.Hidden" /> and <see cref="ComponentState.ReadOnly" />
 65    /// </summary>
 66    /// <returns>A new <see cref="ThemeNavigator" /> instance with all interactive component states selected.</returns>
 67    public ThemeNavigator SetAllComponentStates()
 68    {
 94469        var states = Enum.GetValues<ComponentState>().ToList();
 94470        states.Remove(item: ComponentState.Hidden);
 94471        states.Remove(item: ComponentState.ReadOnly);
 72
 94473        return SetComponentStates(items: states.ToArray());
 74    }
 75
 76    /// <summary>Sets all available component types.</summary>
 77    /// <returns>A new <see cref="ThemeNavigator" /> with all <see cref="ComponentType" /> values applied.</returns>
 178    public ThemeNavigator SetAllComponentTypes() => SetComponentTypes(items: Enum.GetValues<ComponentType>());
 79
 80    /// <summary>Sets all available style types.</summary>
 81    /// <returns>A new <see cref="ThemeNavigator" /> with all <see cref="StyleType" /> values applied.</returns>
 182    public ThemeNavigator SetAllStyleTypes() => SetStyleTypes(items: Enum.GetValues<StyleType>());
 83
 84    /// <summary>Sets the component states for this navigator.</summary>
 85    /// <param name="items">An array of <see cref="ComponentState" /> values to include.</param>
 86    /// <returns>A new <see cref="ThemeNavigator" /> with the specified component states.</returns>
 87    public ThemeNavigator SetComponentStates(params ComponentState[] items)
 652188        => this with
 652189        {
 652190            ComponentStates = BuildList(items: items)
 652191        };
 92
 93    /// <summary>Sets the component types for this navigator.</summary>
 94    /// <param name="items">An array of <see cref="ComponentType" /> values to include.</param>
 95    /// <returns>A new <see cref="ThemeNavigator" /> with the specified component types.</returns>
 96    public ThemeNavigator SetComponentTypes(params ComponentType[] items)
 650297        => this with
 650298        {
 650299            ComponentTypes = BuildList(items: items)
 6502100        };
 101
 102    /// <summary>Configures this navigator for high-contrast or standard light/dark theme variants.</summary>
 103    /// <param name="isHighContrast">Whether high-contrast themes should be targeted.</param>
 104    /// <returns>A new <see cref="ThemeNavigator" /> configured for the specified contrast context.</returns>
 105    internal ThemeNavigator SetContrastThemeTypes(bool isHighContrast)
 945106        => isHighContrast
 945107            ? SetThemeTypes(ThemeType.HighContrastLight, ThemeType.HighContrastDark)
 945108            : SetThemeTypes(ThemeType.Light, ThemeType.Dark);
 109
 110    /// <summary>Sets the style types for this navigator.</summary>
 111    /// <param name="items">An array of <see cref="StyleType" /> values to include.</param>
 112    /// <returns>A new <see cref="ThemeNavigator" /> with the specified style types.</returns>
 113    public ThemeNavigator SetStyleTypes(params StyleType[] items)
 6466114        => this with
 6466115        {
 6466116            StyleTypes = BuildList(items: items)
 6466117        };
 118
 119    /// <summary>
 120    /// Sets the specific theme type to navigate, validating that system and high-contrast variants are excluded.
 121    /// </summary>
 122    /// <param name="themeType">The <see cref="ThemeType" /> to target.</param>
 123    /// <returns>A new <see cref="ThemeNavigator" /> configured with the specified theme type.</returns>
 124    /// <exception cref="AryArgumentException">Thrown if the specified theme type is invalid for this context.</exceptio
 125    public ThemeNavigator SetThemeType(ThemeType themeType)
 26126        => themeType is ThemeType.System or ThemeType.HighContrastDark or ThemeType.HighContrastLight
 26127            ? throw new AryArgumentException(message: "Invalid theme type", argName: nameof(themeType))
 26128            : SetThemeTypes(items: themeType);
 129
 130    /// <summary>Sets the theme types for this navigator.</summary>
 131    /// <param name="items">An array of <see cref="ThemeType" /> values to include.</param>
 132    /// <returns>A new <see cref="ThemeNavigator" /> configured with the specified theme types.</returns>
 133    internal ThemeNavigator SetThemeTypes(params ThemeType[] items)
 6512134        => this with
 6512135        {
 6512136            ThemeTypes = BuildList(items: items)
 6512137        };
 138}