< Summary

Information
Class: MyNet.Globalization.Localization.Translation.KeyResolving.TranslationKeyResolver
Assembly: MyNet.Globalization
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Globalization/Localization/Translation/KeyResolving/TranslationKeyResolver.cs
Tag: 323_28699572109
Line coverage
100%
Covered lines: 49
Uncovered lines: 0
Coverable lines: 49
Total lines: 167
Line coverage: 100%
Branch coverage
95%
Covered branches: 21
Total branches: 22
Branch coverage: 95.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
Resolve(...)100%1010100%
ResolvePluralizedKey(...)100%11100%
ResolveStyledKey(...)100%11100%
BuildKey(...)100%11100%
GetPolicy(...)100%88100%
ResolveStyleSuffixes(...)100%11100%
ResolvePluralSuffixes(...)75%4483.33%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Globalization/Localization/Translation/KeyResolving/TranslationKeyResolver.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="TranslationKeyResolver.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.Diagnostics.CodeAnalysis;
 10using System.Globalization;
 11using System.Linq;
 12using MyNet.Globalization.Inflection;
 13
 14namespace MyNet.Globalization.Localization.Translation.KeyResolving;
 15
 16/// <summary>
 17/// Current implementation of <see cref="ITranslationKeyResolver"/>.
 18/// </summary>
 19public sealed class TranslationKeyResolver(IPluralizationService pluralizationService) : ITranslationKeyResolver
 20{
 21    public const string DefaultSuffix = "";
 22    public const string SymbolSuffix = nameof(DisplayStyle.Symbol);
 23    public const string AbbreviationSuffix = "Abbr";
 24    public const string ShortSuffix = nameof(DisplayStyle.Short);
 25    public const string NarrowSuffix = nameof(DisplayStyle.Narrow);
 26
 27    public const string PluralSuffix = "Plural";
 28    public const string ZeroSuffix = "Zero";
 29
 1230    private static readonly Dictionary<DisplayStyle, string> StyleSuffix = new()
 1231    {
 1232        { DisplayStyle.Default, DefaultSuffix },
 1233        { DisplayStyle.Symbol, SymbolSuffix },
 1234        { DisplayStyle.Abbreviation, AbbreviationSuffix },
 1235        { DisplayStyle.Short, ShortSuffix },
 1236        { DisplayStyle.Narrow, NarrowSuffix }
 1237    };
 38
 1239    private static readonly Dictionary<DisplayStyle, DisplayStyle[]> StyleSuffixes = new()
 1240    {
 1241        { DisplayStyle.Default, [DisplayStyle.Default] },
 1242        { DisplayStyle.Symbol, [DisplayStyle.Symbol, DisplayStyle.Abbreviation] },
 1243        { DisplayStyle.Abbreviation, [DisplayStyle.Abbreviation, DisplayStyle.Short, DisplayStyle.Narrow] },
 1244        { DisplayStyle.Short, [DisplayStyle.Short, DisplayStyle.Narrow, DisplayStyle.Abbreviation] },
 1245        { DisplayStyle.Narrow, [DisplayStyle.Narrow, DisplayStyle.Short, DisplayStyle.Abbreviation] }
 1246    };
 47
 48    /// <inheritdoc />
 49    public IReadOnlyCollection<TranslationKeyCandidate> Resolve(string baseKey, TranslationOptions options, CultureInfo 
 50    {
 100251        ArgumentException.ThrowIfNullOrWhiteSpace(baseKey);
 52
 100253        var list = new List<TranslationKeyCandidate>();
 100254        var seen = new HashSet<TranslationKeyCandidate>();
 55
 100256        var pluralSuffixes = options.Quantity.HasValue ? ResolvePluralSuffixes(options.Quantity.Value, culture) : [];
 100257        var styles = StyleSuffixes[options.Style];
 58
 59        // --------------------------------------------------
 60        // 1. MOST SPECIFIC: STYLE + PLURAL
 61        // --------------------------------------------------
 261662        foreach (var plural in pluralSuffixes)
 63        {
 123664            foreach (var style in styles)
 31265                add(baseKey, style, plural);
 66        }
 67
 68        // --------------------------------------------------
 69        // 2. PLURAL ONLY
 70        // --------------------------------------------------
 261671        foreach (var plural in pluralSuffixes)
 30672            add(baseKey, pluralSuffix: plural);
 73
 74        // --------------------------------------------------
 75        // 3. STYLE ONLY
 76        // --------------------------------------------------
 406877        foreach (var style in styles)
 103278            add(baseKey, style);
 79
 80        // --------------------------------------------------
 81        // 4. FALLBACK BASE KEY
 82        // --------------------------------------------------
 100283        add(baseKey);
 84
 100285        return list;
 86
 87        void add(string key, DisplayStyle? style = null, string? pluralSuffix = null)
 88        {
 89            var finalKey = BuildKey(key, style.HasValue ? StyleSuffix[style.Value] : null, pluralSuffix);
 90
 91            var policy = GetPolicy(style, pluralSuffix);
 92
 93            var candidate = new TranslationKeyCandidate(finalKey, policy);
 94            if (seen.Add(candidate))
 95                list.Add(candidate);
 96        }
 97    }
 98
 99    /// <inheritdoc />
 100    public string ResolvePluralizedKey(string baseKey, decimal count, CultureInfo culture)
 101    {
 6102        ArgumentException.ThrowIfNullOrWhiteSpace(baseKey);
 103
 6104        var suffix = ResolvePluralSuffixes(count, culture).FirstOrDefault();
 105
 6106        return BuildKey(baseKey, pluralSuffix: suffix);
 107    }
 108
 109    /// <inheritdoc />
 110    public string ResolveStyledKey(string baseKey, DisplayStyle style, CultureInfo culture)
 111    {
 3112        ArgumentException.ThrowIfNullOrWhiteSpace(baseKey);
 113
 3114        var suffix = ResolveStyleSuffixes(style).FirstOrDefault();
 115
 3116        return BuildKey(baseKey, styleSuffix: suffix);
 117    }
 118
 119    /// <summary>
 120    /// Builds a translation key by combining the base key with the specified suffix. The resulting key is formed by con
 121    /// </summary>
 122    /// <param name="baseKey">The base translation key.</param>
 123    /// <param name="styleSuffix">The optional style suffix to append to the base key.</param>
 124    /// <param name="pluralSuffix">The optional plural suffix to append to the base key.</param>
 125    /// <returns>The combined translation key.</returns>
 2661126    private static string BuildKey(string baseKey, string? styleSuffix = null, string? pluralSuffix = null) => string.Co
 127
 128    /// <summary>
 129    /// Determines the translation fallback policy based on the presence of style and plural suffixes. The method evalua
 130    /// </summary>
 131    /// <param name="style">The display style of the translation key.</param>
 132    /// <param name="pluralSuffix">The plural suffix of the translation key.</param>
 133    /// <returns>The determined translation fallback policy.</returns>
 134    [SuppressMessage("ReSharper", "ConvertIfStatementToReturnStatement", Justification = "Readability")]
 135    private static TranslationFallbackPolicy GetPolicy(DisplayStyle? style, string? pluralSuffix)
 136    {
 137        // Symbol / Abbreviation => always strict
 2652138        if (style is DisplayStyle.Symbol or DisplayStyle.Abbreviation)
 18139            return TranslationFallbackPolicy.Strict;
 140
 141        // Plural/Zero => strict (grammatical decision already made)
 2634142        if (!string.IsNullOrWhiteSpace(pluralSuffix))
 387143            return TranslationFallbackPolicy.Strict;
 144
 145        // Current / Short / Narrow => flexible
 2247146        return TranslationFallbackPolicy.Flexible;
 147    }
 148
 149    /// <summary>
 150    /// Resolves display style suffixes ordered by preference.
 151    /// </summary>
 3152    private static IReadOnlyCollection<string> ResolveStyleSuffixes(DisplayStyle style) => [.. StyleSuffixes[style].Sele
 153
 154    /// <summary>
 155    /// Resolves plural suffixes for the given count and culture, ordered by preference. The method first determines the
 156    /// </summary>
 157    /// <param name="count">The count to determine the plural category.</param>
 158    /// <param name="culture">The culture to use for pluralization rules.</param>
 159    /// <returns>An enumerable of plural suffixes ordered by preference.</returns>
 312160    private IReadOnlyCollection<string> ResolvePluralSuffixes(decimal count, CultureInfo culture) => pluralizationServic
 312161    {
 3162        PluralCategory.Zero => [ZeroSuffix],
 114163        PluralCategory.Singular => [DefaultSuffix],
 195164        _ => [PluralSuffix]
 312165    };
 166}
 167