diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/CompositeFormat.cs b/src/libraries/System.Private.CoreLib/src/System/Text/CompositeFormat.cs index a29fdbbada334..3ecac9036eb2e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/CompositeFormat.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/CompositeFormat.cs @@ -85,31 +85,13 @@ public static CompositeFormat Parse([StringSyntax(StringSyntaxAttribute.Composit return new CompositeFormat(format, segments.ToArray()); } - /// Try to parse the composite format string . - /// The string to parse. - /// The parsed if parsing was successful; otherwise, null. - /// the can be parsed successfully; otherwise, . - public static bool TryParse([StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? format, [NotNullWhen(true)] out CompositeFormat? compositeFormat) - { - if (format is not null) - { - var segments = new List<(string? Literal, int ArgIndex, int Alignment, string? Format)>(); - int failureOffset = default; - ExceptionResource failureReason = default; - if (TryParseLiterals(format, segments, ref failureOffset, ref failureReason)) - { - compositeFormat = new CompositeFormat(format, segments.ToArray()); - return true; - } - } - - compositeFormat = null; - return false; - } - /// Gets the original composite format string used to create this instance. public string Format { get; } + /// Gets the minimum number of arguments that must be passed to a formatting operation using this . + /// It's permissible to supply more arguments than this value, but it's an error to pass fewer. + public int MinimumArgumentCount => _argsRequired; + /// Throws an exception if the specified number of arguments is fewer than the number required. /// The number of arguments provided by the caller. /// An insufficient number of arguments were provided. diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index dd1f0862bbeb9..d7a93015a7d5b 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -14194,8 +14194,8 @@ public sealed class CompositeFormat { internal CompositeFormat() { } public static System.Text.CompositeFormat Parse([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format) { throw null; } - public static bool TryParse([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("CompositeFormat")] string format, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Text.CompositeFormat? compositeFormat) { throw null; } public string Format { get { throw null; } } + public int MinimumArgumentCount { get { throw null; } } } public abstract partial class Decoder { diff --git a/src/libraries/System.Runtime/tests/System/Text/CompositeFormatTests.cs b/src/libraries/System.Runtime/tests/System/Text/CompositeFormatTests.cs index c481638159ff3..bdfde206c850f 100644 --- a/src/libraries/System.Runtime/tests/System/Text/CompositeFormatTests.cs +++ b/src/libraries/System.Runtime/tests/System/Text/CompositeFormatTests.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Linq; using Xunit; namespace System.Text.Tests @@ -13,9 +14,6 @@ public void NullArgument_Throws() { AssertExtensions.Throws("format", () => CompositeFormat.Parse(null)); - Assert.False(CompositeFormat.TryParse(null, out CompositeFormat? compositeFormat)); - Assert.Null(compositeFormat); - AssertExtensions.Throws("format", () => string.Format(null, (CompositeFormat)null, 0)); AssertExtensions.Throws("format", () => string.Format(null, (CompositeFormat)null, 0, 0)); AssertExtensions.Throws("format", () => string.Format(null, (CompositeFormat)null, 0, 0, 0)); @@ -55,6 +53,30 @@ public static void DebuggerDisplay_ShowsFormat() Assert.Equal($"\"{format}\"", DebuggerAttributes.ValidateDebuggerDisplayReferences(cf)); } + [Theory] + [InlineData("", 0)] + [InlineData("testing 123", 0)] + [InlineData("testing {{123}}", 0)] + [InlineData("{0}", 1)] + [InlineData("{0} {1}", 2)] + [InlineData("{2}", 3)] + [InlineData("{2} {0}", 3)] + [InlineData("{1} {34} {3}", 35)] + public static void MinimumArgumentCount_MatchesExpectedValue(string format, int expected) + { + CompositeFormat cf = CompositeFormat.Parse(format); + + Assert.Equal(expected, cf.MinimumArgumentCount); + + string s = string.Format(null, cf, Enumerable.Repeat((object)"arg", expected).ToArray()); + Assert.NotNull(s); + + if (expected != 0) + { + Assert.Throws(() => string.Format(null, cf, Enumerable.Repeat((object)"arg", expected - 1).ToArray())); + } + } + [Theory] [MemberData(nameof(System.Tests.StringTests.Format_Valid_TestData), MemberType = typeof(System.Tests.StringTests))] public static void StringFormat_Valid(IFormatProvider provider, string format, object[] values, string expected) @@ -63,10 +85,6 @@ public static void StringFormat_Valid(IFormatProvider provider, string format, o Assert.NotNull(cf); Assert.Same(format, cf.Format); - Assert.True(CompositeFormat.TryParse(format, out CompositeFormat? cf2)); - Assert.NotNull(cf2); - Assert.Same(format, cf2.Format); - Assert.Equal(expected, string.Format(provider, cf, values)); Assert.Equal(expected, string.Format(provider, cf, (ReadOnlySpan)values)); @@ -95,10 +113,6 @@ public static void StringBuilderAppendFormat_Valid(IFormatProvider provider, str Assert.NotNull(cf); Assert.Same(format, cf.Format); - Assert.True(CompositeFormat.TryParse(format, out CompositeFormat? cf2)); - Assert.NotNull(cf2); - Assert.Same(format, cf2.Format); - var sb = new StringBuilder(); Assert.Same(sb, sb.AppendFormat(provider, cf, values)); @@ -135,10 +149,6 @@ public static void MemoryExtensionsTryWrite_Valid(IFormatProvider provider, stri Assert.NotNull(cf); Assert.Same(format, cf.Format); - Assert.True(CompositeFormat.TryParse(format, out CompositeFormat? cf2)); - Assert.NotNull(cf2); - Assert.Same(format, cf2.Format); - char[] dest = new char[expected.Length]; int charsWritten; @@ -189,9 +199,6 @@ public static void Parse_Invalid_FormatExceptionFromFormat(IFormatProvider provi _ = args; Assert.Throws(() => CompositeFormat.Parse(format)); - - Assert.False(CompositeFormat.TryParse(format, out CompositeFormat? compositeFormat)); - Assert.Null(compositeFormat); } [Theory]