< Summary

Information
Class: MyNet.Globalization.Inflection.Inflector
Assembly: MyNet.Globalization
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Globalization/Inflection/Inflector.cs
Tag: 323_28699572109
Line coverage
100%
Covered lines: 26
Uncovered lines: 0
Coverable lines: 26
Total lines: 132
Line coverage: 100%
Branch coverage
100%
Covered branches: 14
Total branches: 14
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Create(...)100%11100%
Pluralize(...)100%11100%
Singularize(...)100%11100%
get_UsePluralForZero()100%11100%
IsPlural(...)100%44100%
GetPluralCategory(...)100%44100%
ApplyFirstMatchingRule(...)100%66100%
IsUncountable(...)100%11100%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Globalization/Inflection/Inflector.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="Inflector.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Collections.Immutable;
 9using System.Globalization;
 10
 11namespace MyNet.Globalization.Inflection;
 12
 13/// <summary>
 14/// Represents an immutable implementation of the IInflector interface, which provides methods for pluralizing and singu
 15/// </summary>
 16/// <remarks>
 17/// Initializes a new instance of the <see cref="Inflector"/> class with the specified culture and inflection rules. The
 18/// </remarks>
 19/// <param name="culture">The culture to use for inflection operations.</param>
 20/// <param name="rules">The inflection rules to apply.</param>
 21public class Inflector(CultureInfo culture, InflectionRules rules) : IInflector
 22{
 23    /// <summary>
 24    /// Creates a new instance of the <see cref="Inflector"/> class with the specified culture. This factory method prov
 25    /// </summary>
 26    /// <param name="culture">The culture to use for inflection operations.</param>
 27    /// <returns>An instance of the <see cref="InflectorBuilder"/> class.</returns>
 1828    public static InflectorBuilder Create(CultureInfo culture) => new(culture);
 29
 30    /// <summary>
 31    /// Gets the culture associated with this inflector, which is used for inflection operations. The culture is set dur
 32    /// </summary>
 33    public CultureInfo Culture { get; } = culture;
 34
 35    /// <summary>
 36    /// Returns the plural form of the specified word based on the inflection rules of the language.
 37    /// Uncountable words are returned unchanged.
 38    /// Rules are evaluated last-added-first, so more specific rules (irregulars) added after general rules take priorit
 39    /// </summary>
 40    /// <param name="word">The word to pluralize.</param>
 41    /// <returns>The plural form of the word, or the original word if no rules match or the word is uncountable.</return
 42    /// <exception cref="ArgumentException">Thrown when the word is null or empty.</exception>
 43    public virtual string Pluralize(string word)
 44    {
 285045        ArgumentException.ThrowIfNullOrEmpty(word);
 46
 285047        return ApplyFirstMatchingRule(rules.Plurals, word);
 48    }
 49
 50    /// <summary>
 51    /// Returns the singular form of the specified word based on the inflection rules of the language.
 52    /// Uncountable words are returned unchanged.
 53    /// Rules are evaluated last-added-first, so more specific rules (irregulars) added after general rules take priorit
 54    /// </summary>
 55    /// <param name="word">The word to singularize.</param>
 56    /// <returns>The singular form of the word, or the original word if no rules match or the word is uncountable.</retu
 57    /// <exception cref="ArgumentException">Thrown when the word is null or empty.</exception>
 58    public virtual string Singularize(string word)
 59    {
 234660        ArgumentException.ThrowIfNullOrEmpty(word);
 61
 234662        return ApplyFirstMatchingRule(rules.Singulars, word);
 63    }
 64
 65    /// <summary>
 66    /// Gets a value indicating whether quantities in the <see cref="PluralCategory.Zero"/> category should use the plur
 67    /// </summary>
 968    protected virtual bool UsePluralForZero => true;
 69
 70    /// <summary>
 71    /// Returns whether the specified quantity should use the plural form for this language.
 72    /// Current behavior maps categories explicitly and keeps zero configurable via <see cref="UsePluralForZero"/>.
 73    /// </summary>
 74    /// <param name="count">The quantity to evaluate.</param>
 75    /// <returns><c>true</c> when the plural form should be used; otherwise <c>false</c>.</returns>
 76    public virtual bool IsPlural(decimal count)
 54377        => GetPluralCategory(count) switch
 54378        {
 1279            PluralCategory.Singular => false,
 980            PluralCategory.Zero => UsePluralForZero,
 52281            _ => true
 54382        };
 83
 84    /// <summary>
 85    /// Returns the plural category of the specified quantity.
 86    /// <list type="bullet">
 87    ///   <item><c>0</c> → <see cref="PluralCategory.Zero"/> (treated as plural in English; language-dependent in others
 88    ///   <item><c>1</c> → <see cref="PluralCategory.Singular"/></item>
 89    ///   <item>anything else → <see cref="PluralCategory.Other"/></item>
 90    /// </list>
 91    /// Override in language-specific subclasses to support <see cref="PluralCategory.Dual"/>, <see cref="PluralCategory
 92    /// </summary>
 93    /// <param name="count">The quantity to evaluate.</param>
 94    /// <returns>The plural category corresponding to the specified quantity.</returns>
 95    public virtual PluralCategory GetPluralCategory(decimal count)
 85596        => Math.Abs(count) switch
 85597        {
 1298            0 => PluralCategory.Zero,
 12699            1 => PluralCategory.Singular,
 717100            _ => PluralCategory.Other
 855101        };
 102
 103    /// <summary>
 104    /// Applies the first matching inflection rule from the provided list of rules to the given word. The method iterate
 105    /// </summary>
 106    /// <param name="inflectionRules">The list of inflection rules to apply.</param>
 107    /// <param name="word">The word to which the rules should be applied.</param>
 108    /// <returns>The result of applying the first matching rule, or the original word if no rules match.</returns>
 109    protected virtual string ApplyFirstMatchingRule(ImmutableArray<InflectionRule> inflectionRules, string word)
 110    {
 5196111        if (IsUncountable(word))
 618112            return word;
 113
 300492114        for (var i = inflectionRules.Length - 1; i >= 0; i--)
 115        {
 149181116            var result = inflectionRules[i].Apply(word);
 117
 149181118            if (!string.IsNullOrEmpty(result))
 3513119                return result;
 120        }
 121
 1065122        return word;
 123    }
 124
 125    /// <summary>
 126    /// Determines whether the specified word is uncountable, meaning that it does not have distinct singular and plural
 127    /// </summary>
 128    /// <param name="word">The word to check for uncountability.</param>
 129    /// <returns>True if the word is uncountable; otherwise, false.</returns>
 5196130    protected virtual bool IsUncountable(string word) => rules.Uncountables.Contains(word);
 131}
 132