< Summary

Information
Class: MyNet.Humanizer.Formatting.Collections.ListFormatter
Assembly: MyNet.Humanizer
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Humanizer/Formatting/Collections/ListFormatter.cs
Tag: 323_28699572109
Line coverage
100%
Covered lines: 1
Uncovered lines: 0
Coverable lines: 1
Total lines: 117
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Humanizer/Formatting/Collections/ListFormatter.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="ListFormatter.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.Globalization.Localization.Translation;
 12using MyNet.Humanizer.Resources;
 13
 14namespace MyNet.Humanizer.Formatting.Collections;
 15
 16/// <summary>
 17/// Formats lists of items into human readable strings. This class is sealed and cannot be inherited. It provides a conv
 18/// </summary>
 19/// <param name="translationService">The translation service used to translate resource keys.</param>
 20/// <param name="culture">The culture used for humanization and formatting.</param>
 21public sealed class ListFormatter(ITranslationService translationService, CultureInfo culture)
 9622    : ListFormatterBase(translationService, culture);
 23
 24/// <summary>
 25/// Base class for list formatters. Provides common logic for formatting lists of items into human readable strings.
 26/// </summary>
 27public abstract class ListFormatterBase(ITranslationService translationService, CultureInfo supportedCulture) : IListFor
 28{
 29    /// <summary>
 30    /// Gets the supported culture for this humanizer.
 31    /// </summary>
 32    public CultureInfo Culture => supportedCulture;
 33
 34    /// <summary>
 35    /// Gets the separator used to separate the last two items in a list when the conjunction is "and".
 36    /// </summary>
 37    protected virtual string AndSeparator { get; } = translationService.Translate(nameof(ListResources.AndSeparator), Tr
 38
 39    /// <summary>
 40    /// Gets the separator used to separate the last two items in a list when the conjunction is "or".
 41    /// </summary>
 42    protected virtual string OrSeparator { get; } = translationService.Translate(nameof(ListResources.OrSeparator), Tran
 43
 44    /// <summary>
 45    /// Formats a list of items into a human readable string.
 46    /// </summary>
 47    /// <param name="items">The list of items to format.</param>
 48    /// <param name="options">The formatting options to use.</param>
 49    /// <returns>A human readable string representation of the list.</returns>
 50    /// <exception cref="ArgumentNullException">Thrown when the items parameter is null.</exception>
 51    public string Format(IEnumerable<string?> items, ListFormattingOptions? options = null)
 52    {
 53        ArgumentNullException.ThrowIfNull(items);
 54
 55        options ??= ListFormattingOptions.Default;
 56
 57        var values = items
 58            .Select(Normalize)
 59            .Where(x => !options.IgnoreNullOrWhiteSpace || !string.IsNullOrWhiteSpace(x))
 60            .ToArray();
 61
 62        return values.Length switch
 63        {
 64            0 => string.Empty,
 65            1 => values[0],
 66            2 => FormatTwoItems(values, options),
 67            _ => FormatManyItems(values, options)
 68        };
 69    }
 70
 71    /// <summary>
 72    /// Normalizes a string value by trimming it and replacing null with an empty string. This method can be overridden 
 73    /// </summary>
 74    /// <param name="value">The string value to normalize.</param>
 75    /// <returns>The normalized string value.</returns>
 76    protected virtual string Normalize(string? value) => value?.Trim() ?? string.Empty;
 77
 78    /// <summary>
 79    /// Formats a list of two items into a human readable string using the appropriate conjunction and separator based o
 80    /// </summary>
 81    /// <param name="items">The array of two items to format.</param>
 82    /// <param name="options">The formatting options to use.</param>
 83    /// <returns>A human readable string representation of the two items.</returns>
 84    protected virtual string FormatTwoItems(string[] items, ListFormattingOptions options) => string.Concat(items[0], Ge
 85
 86    /// <summary>
 87    /// Formats a list of three or more items into a human readable string by joining the items with the appropriate sep
 88    /// </summary>
 89    /// <param name="items">The array of items to format.</param>
 90    /// <param name="options">The formatting options to use.</param>
 91    /// <returns>A human readable string representation of the items.</returns>
 92    protected virtual string FormatManyItems(string[] items, ListFormattingOptions options)
 93    {
 94        var lastIndex = items.Length - 1;
 95
 96        var start = string.Join(options.Separator, items.AsSpan(0, lastIndex).ToArray());
 97
 98        var separator = options.UseOxfordComma && options.Conjunction != ListConjunction.None ? options.Separator.TrimEn
 99
 100        return string.Concat(start, separator, GetFinalSeparator(options), items[lastIndex]);
 101    }
 102
 103    /// <summary>
 104    /// Gets the appropriate separator to use between the last two items in a list based on the conjunction specified in
 105    /// </summary>
 106    /// <param name="options">The formatting options to use.</param>
 107    /// <returns>The appropriate separator string.</returns>
 108    protected virtual string GetFinalSeparator(ListFormattingOptions options)
 109        => options.Conjunction switch
 110        {
 111            ListConjunction.Or => $" {OrSeparator.Trim()} ",
 112            ListConjunction.None => options.Separator,
 113            ListConjunction.Ampersand => " & ",
 114            _ => $" {AndSeparator.Trim()} "
 115        };
 116}
 117