mirror of
				https://github.com/nsnail/spectre.console.git
				synced 2025-11-01 01:25:27 +08:00 
			
		
		
		
	Add culture option to TypeConverterHelper, TextPrompt and AnsiConsole (#1014)
* Add culture option to TypeConverterHelper, TextPrompt and AnsiConsole * Add IHasCulture interface
This commit is contained in:
		| @@ -34,6 +34,21 @@ public static partial class AnsiConsoleExtensions | ||||
|         return new TextPrompt<T>(prompt).Show(console); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Displays a prompt to the user. | ||||
|     /// </summary> | ||||
|     /// <typeparam name="T">The prompt result type.</typeparam> | ||||
|     /// <param name="console">The console.</param> | ||||
|     /// <param name="prompt">The prompt markup text.</param> | ||||
|     /// <param name="culture">Specific CultureInfo to use when converting input.</param> | ||||
|     /// <returns>The prompt input result.</returns> | ||||
|     public static T Ask<T>(this IAnsiConsole console, string prompt, CultureInfo? culture) | ||||
|     { | ||||
|         var textPrompt = new TextPrompt<T>(prompt); | ||||
|         textPrompt.Culture = culture; | ||||
|         return textPrompt.Show(console); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Displays a prompt with two choices, yes or no. | ||||
|     /// </summary> | ||||
|   | ||||
| @@ -21,6 +21,28 @@ internal static class TypeConverterHelper | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static bool TryConvertFromStringWithCulture<T>(string input, CultureInfo? info, [MaybeNull] out T result) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             if (info == null) | ||||
|             { | ||||
|                 return TryConvertFromString<T>(input, out result); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 result = (T)GetTypeConverter<T>().ConvertFromString(null!, info, input); | ||||
|             } | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|         catch | ||||
|         { | ||||
|             result = default; | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static TypeConverter GetTypeConverter<T>() | ||||
|     { | ||||
|         var converter = TypeDescriptor.GetConverter(typeof(T)); | ||||
|   | ||||
| @@ -4,7 +4,7 @@ namespace Spectre.Console; | ||||
| /// Represents a prompt. | ||||
| /// </summary> | ||||
| /// <typeparam name="T">The prompt result type.</typeparam> | ||||
| public sealed class TextPrompt<T> : IPrompt<T> | ||||
| public sealed class TextPrompt<T> : IPrompt<T>, IHasCulture | ||||
| { | ||||
|     private readonly string _prompt; | ||||
|     private readonly StringComparer? _comparer; | ||||
| @@ -19,6 +19,11 @@ public sealed class TextPrompt<T> : IPrompt<T> | ||||
|     /// </summary> | ||||
|     public List<T> Choices { get; } = new List<T>(); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Gets or sets the culture to use when converting input to object. | ||||
|     /// </summary> | ||||
|     public CultureInfo? Culture { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Gets or sets the message for invalid choices. | ||||
|     /// </summary> | ||||
| @@ -28,12 +33,12 @@ public sealed class TextPrompt<T> : IPrompt<T> | ||||
|     /// Gets or sets a value indicating whether input should | ||||
|     /// be hidden in the console. | ||||
|     /// </summary> | ||||
|     public bool IsSecret { get; set; } | ||||
|  | ||||
|     public bool IsSecret { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Gets or sets the character to use while masking | ||||
|     /// Gets or sets the character to use while masking | ||||
|     /// a secret prompt. | ||||
|     /// </summary> | ||||
|     /// </summary> | ||||
|     public char? Mask { get; set; } = '*'; | ||||
|  | ||||
|     /// <summary> | ||||
| @@ -131,7 +136,7 @@ public sealed class TextPrompt<T> : IPrompt<T> | ||||
|                 if (string.IsNullOrWhiteSpace(input)) | ||||
|                 { | ||||
|                     if (DefaultValue != null) | ||||
|                     { | ||||
|                     { | ||||
|                         var defaultValue = converter(DefaultValue.Value); | ||||
|                         console.Write(IsSecret ? defaultValue.Mask(Mask) : defaultValue, promptStyle); | ||||
|                         console.WriteLine(); | ||||
| @@ -160,7 +165,7 @@ public sealed class TextPrompt<T> : IPrompt<T> | ||||
|                         continue; | ||||
|                     } | ||||
|                 } | ||||
|                 else if (!TypeConverterHelper.TryConvertFromString<T>(input, out result) || result == null) | ||||
|                 else if (!TypeConverterHelper.TryConvertFromStringWithCulture<T>(input, Culture, out result) || result == null) | ||||
|                 { | ||||
|                     console.MarkupLine(ValidationErrorMessage); | ||||
|                     WritePrompt(console); | ||||
| @@ -208,8 +213,8 @@ public sealed class TextPrompt<T> : IPrompt<T> | ||||
|         { | ||||
|             appendSuffix = true; | ||||
|             var converter = Converter ?? TypeConverterHelper.ConvertToString; | ||||
|             var defaultValueStyle = DefaultValueStyle?.ToMarkup() ?? "green"; | ||||
|             var defaultValue = converter(DefaultValue.Value); | ||||
|             var defaultValueStyle = DefaultValueStyle?.ToMarkup() ?? "green"; | ||||
|             var defaultValue = converter(DefaultValue.Value); | ||||
|  | ||||
|             builder.AppendFormat( | ||||
|                 CultureInfo.InvariantCulture, | ||||
|   | ||||
| @@ -20,4 +20,35 @@ public partial class AnsiConsoleTests | ||||
|             result.ShouldBe(expected); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public sealed class Ask | ||||
|     { | ||||
|         [Fact] | ||||
|         public void Should_Return_Correct_DateTime_When_Asked_PL_Culture() | ||||
|         { | ||||
|             // Given | ||||
|             var console = new TestConsole().EmitAnsiSequences(); | ||||
|             console.Input.PushTextWithEnter("1/2/1998"); | ||||
|  | ||||
|             // When | ||||
|             var dateTime = console.Ask<DateTime>(string.Empty, CultureInfo.GetCultureInfo("pl-PL")); | ||||
|  | ||||
|             // Then | ||||
|             dateTime.ShouldBe(new DateTime(1998, 2, 1)); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void Should_Return_Correct_DateTime_When_Asked_US_Culture() | ||||
|         { | ||||
|             // Given | ||||
|             var console = new TestConsole().EmitAnsiSequences(); | ||||
|             console.Input.PushTextWithEnter("2/1/1998"); | ||||
|  | ||||
|             // When | ||||
|             var dateTime = console.Ask<DateTime>(string.Empty, CultureInfo.GetCultureInfo("en-US")); | ||||
|  | ||||
|             // Then | ||||
|             dateTime.ShouldBe(new DateTime(1998, 2, 1)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Łukasz Sowa
					Łukasz Sowa