Skip to content

[API Proposal]: Missing CompositeFormat features #85099

@geeknoid

Description

@geeknoid

EDITED BY @stephentoub 4/24/2023:

  • I removed the suggested TryParse overload. I don't currently see the need.
  • I renamed the proposed property, but we can probably come up with a better name, too.
public class CompositeFormat
{
+    // Gets the minimum number of arguments that must be passed to a formatting operation using this CompositeFormat.
+    // Providing more than this is fine, but less than this will result in an exception during formatting.
+    public int RequiredArgumentCount { get; }
}

This is just exposing a number the implementation already has in a field.


Background and motivation

The new CompositeFormat functionality in .NET 8 is missing a few features which hampers its usability. It would be great to see these features introduced.

  • A property that returns the number of arguments required when trying to format a string. The specific scenario where we need this is in order to allow the user to specify how to format some output within a config file. In our redaction logic, the customer can decide to format the output as simply "{0}" which means no redaction, or "REDACTED", or maybe "redacted:{0}". Whatever the customer wants. As we parse the format string, we need to know that the user specify either one argument value or none, so that we can produce a meaningful error message and we call the ultimate formatting function with the right number of args.

  • Return meaningful error messages. Right now, parsing composite format strings will return a single "invalid format" error. We have giant megabyte-sized format strings, and getting a single "you did something bad, but we're not telling you what it is" error message isn't a good UX. Our existing parser has error messages like $"Dangling }} in format string at position {pos}" or
    $"Missing argument index in format string at position {pos}". Ideally, the exception text for the Parse function should be refined to help users solve their problem, and the TryParse function should similarly return this error text.

API Proposal

namespace System.Text;

public class CompositeFormat
{
    /// <summary>
    /// Gets the number of arguments needed to successfully format this instance.
    /// </summary>
    public int NumArgumentsNeeded { get; }

    /// <summary>
    ///  Parses a format string and produces a high-quality error string in case of malformed input.
    /// </summary>
    public static bool TryParse([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? format, [NotNullWhen(true)] out CompositeFormat? compositeFormat, [NotNullWhen(false)] string? error);

API Usage

    if (CompositeFormat.TryParse(formatStringFromConfig, out var cf, out var error);
    {
        if (cf.NumArgumentsNeeded != 0 && cf.NumArgumentsNeeded != 1)
        {
            logger.LogError($"Invalid number of arguments in format string, expecting 0 or 1 arguments but got {cf.NumArgumentsNeeded}");
            return false;
        }
    }
    else
    {
        logger.LogError($"Malformed format string: {error}");
        return false;
    }

    if (cf.NumArgumentsNeeded == 0)
    {
        return string.Format(cf);
    }

    return string.Format(cf, argToFormat);

Alternative Designs

No response

Risks

No response

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedarea-System.RuntimeblockingMarks issues that we want to fast track in order to unblock other important work

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions