AutoSpectre.SourceGeneration 0.9.0

dotnet add package AutoSpectre.SourceGeneration --version 0.9.0                
NuGet\Install-Package AutoSpectre.SourceGeneration -Version 0.9.0                
此命令应在 Visual Studio 的包管理器控制台中使用,因为它使用 NuGet 模块版本的 Install-Package.
<PackageReference Include="AutoSpectre.SourceGeneration" Version="0.9.0" />                
对于支持 PackageReference 的项目,将此 XML 节复制到项目文件中以引用此包。
paket add AutoSpectre.SourceGeneration --version 0.9.0                
#r "nuget: AutoSpectre.SourceGeneration, 0.9.0"                
#r 指令可用于 F# Interactive 和 Polyglot Notebooks。将此内容复制到交互式工具或脚本的源代码中以引用包。
// Install AutoSpectre.SourceGeneration as a Cake Addin
#addin nuget:?package=AutoSpectre.SourceGeneration&version=0.9.0

// Install AutoSpectre.SourceGeneration as a Cake Tool
#tool nuget:?package=AutoSpectre.SourceGeneration&version=0.9.0                

AutoSpectre Source Generation

这允许您使用 AutoSpectreForm 属性装饰一个类,并在该类上使用

  • TextPromptAttribute
  • SelectPromptAttribute

以及 void 或 Task 方法使用

  • TaskStepAttribute

在幕后,将生成一个表单(SpectreFactory),以便使用 Spectre.Console 请求输入

示例

代码

[AutoSpectreForm]
public class Example
{
    [TextPrompt(Title = "Add item")] public int[] IntItems { get; set; } = Array.Empty<int>();

    [TextPrompt(Title = "Enter first name", DefaultValueStyle = "bold")]
    public string? FirstName { get; set; } = "John Doe"; // Default value in prompt

    [TextPrompt(PromptStyle = "green bold")] 
    public bool LeftHanded { get; set; }

    [TextPrompt(Title = "Choose your [red]value[/]" )]
    public SomeEnum Other { get; set; }
    
    [TextPrompt(Secret = true, Mask = '*')]
    public string? Password { get; set; }

    [TextPrompt] public OtherAutoSpectreFormClass ChildForm { get; set; } = new();

    [TextPrompt]
    public IReadOnlyList<OtherAutoSpectreFormClass> Investors { get; set; } = new List<OtherAutoSpectreFormClass>();

    [TaskStep(UseStatus = true, StatusText = "This will take a while", SpinnerType = SpinnerKnownTypes.Christmas, SpinnerStyle = "green on yellow")]
    public void DoSomething(IAnsiConsole console)
    {
        console.Write(new FigletText("A figlet text is needed"));
    }

    [SelectPrompt(WrapAround = true, PageSize = 3,
        MoreChoicesText = "Press down to see more choices", HighlightStyle = "purple")]
    //[SelectPrompt(Source = nameof(ItemSource))]
    public string Item { get; set; } = string.Empty;

    public List<string> ItemSource { get; } = new() { "Alpha", "Bravo", "Charlie" };

    [SelectPrompt(InstructionsText = "Check the special items you want to select")]
    //[SelectPrompt(Converter = nameof(SpecialProjectionConverter))]
    public List<int> SpecialProjection { get; set; } = new();

    public string SpecialProjectionConverter(int source) => $"Number {source}";
    public List<int> SpecialProjectionSource { get; set; } = new() { 1, 2, 3, 4 };

    [TextPrompt]
    // [TextPrompt(Validator = nameof(EnterYearValidator))]
    public int EnterYear { get; set; }

    public string? EnterYearValidator(int year)
    {
        return year <= DateTime.Now.Year ? null : "Year cannot be larger than current year";
    }

    [TextPrompt] public HashSet<string> Names { get; set; } = new(StringComparer.OrdinalIgnoreCase);

    public string? NamesValidator(List<string> items, string newItem)
    {
        if (newItem == "Foobar")
            return "Cannot be Foobar";

        if (items.Contains(newItem))
            return $"{newItem} has already been added";

        return null;
    }

    [TextPrompt] public bool AddExistingName { get; set; }

    [TextPrompt(Condition = nameof(AddExistingName))]
    public string? ExistingName { get; set; }

    [TextPrompt(Condition = nameof(AddExistingName), NegateCondition = true)]
    public string? NewName { get; set; }
}

输出

/// <summary>
/// Helps create and fill <see cref = "Example"/> with values
/// </summary>
public interface IExampleSpectreFactory
{
    Example Get(Example destination = null);
}

/// <summary>
/// Helps create and fill <see cref = "Example"/> with values
/// </summary>
public class ExampleSpectreFactory : IExampleSpectreFactory
{
    public Example Get(Example destination = null)
    {
        IOtherAutoSpectreFormClassSpectreFactory OtherAutoSpectreFormClassSpectreFactory = new OtherAutoSpectreFormClassSpectreFactory();
        destination ??= new ConsoleApp1.Example();
        // Prompt for values for destination.IntItems
        {
            List<int> items = new List<int>();
            bool continuePrompting = true;
            do
            {
                var item = AnsiConsole.Prompt(new TextPrompt<int>("Add item"));
                items.Add(item);
                continuePrompting = AnsiConsole.Confirm("Add more items?");
            }
            while (continuePrompting);
            int[] result = items.ToArray();
            destination.IntItems = result;
        }

        destination.FirstName = AnsiConsole.Prompt(new TextPrompt<string?>("Enter first name").AllowEmpty().DefaultValue("John Doe").DefaultValueStyle("bold"));
        destination.LeftHanded = AnsiConsole.Confirm("Enter [green]LeftHanded[/]");
        destination.Other = AnsiConsole.Prompt(new SelectionPrompt<SomeEnum>().Title("Choose your [red]value[/]").PageSize(10).AddChoices(Enum.GetValues<SomeEnum>()));
        destination.Password = AnsiConsole.Prompt(new TextPrompt<string?>("Enter [green]Password[/]").AllowEmpty().Secret('*'));
        {
            AnsiConsole.MarkupLine("Enter [green]ChildForm[/]");
            var item = OtherAutoSpectreFormClassSpectreFactory.Get();
            destination.ChildForm = item;
        }

        // Prompt for values for destination.Investors
        {
            List<OtherAutoSpectreFormClass> items = new List<OtherAutoSpectreFormClass>();
            bool continuePrompting = true;
            do
            {
                {
                    AnsiConsole.MarkupLine("Enter [green]Investors[/]");
                    var newItem = OtherAutoSpectreFormClassSpectreFactory.Get();
                    items.Add(newItem);
                }

                continuePrompting = AnsiConsole.Confirm("Add more items?");
            }
            while (continuePrompting);
            System.Collections.Generic.IReadOnlyList<ConsoleApp1.OtherAutoSpectreFormClass> result = items;
            destination.Investors = result;
        }

        AnsiConsole.MarkupLine("Calling method [green]DoSomething[/]");
        AnsiConsole.Status().SpinnerStyle("green on yellow").Spinner(Spinner.Known.Christmas).Start("This will take a while", ctx =>
        {
            destination.DoSomething(AnsiConsole.Console);
        });
        destination.Item = AnsiConsole.Prompt(new SelectionPrompt<string>().Title("Enter [green]Item[/]").PageSize(3).WrapAround(true).MoreChoicesText("Press down to see more choices").HighlightStyle("purple").AddChoices(destination.ItemSource.ToArray()));
        destination.SpecialProjection = AnsiConsole.Prompt(new MultiSelectionPrompt<int>().Title("Enter [green]SpecialProjection[/]").UseConverter(destination.SpecialProjectionConverter).PageSize(10).InstructionsText("Check the special items you want to select").AddChoices(destination.SpecialProjectionSource.ToArray()));
        destination.EnterYear = AnsiConsole.Prompt(new TextPrompt<int>("Enter [green]EnterYear[/]").Validate(ctx =>
        {
            var result = destination.EnterYearValidator(ctx);
            return result == null ? ValidationResult.Success() : ValidationResult.Error(result);
        }));
        // Prompt for values for destination.Names
        {
            List<string> items = new List<string>();
            bool continuePrompting = true;
            do
            {
                bool valid = false;
                while (!valid)
                {
                    var item = AnsiConsole.Prompt(new TextPrompt<string>("Enter [green]Names[/]"));
                    var validationResult = destination.NamesValidator(items, item);
                    if (validationResult is { } error)
                    {
                        AnsiConsole.MarkupLine($"[red]{error}[/]");
                        valid = false;
                    }
                    else
                    {
                        valid = true;
                        items.Add(item);
                    }
                }

                continuePrompting = AnsiConsole.Confirm("Add more items?");
            }
            while (continuePrompting);
            System.Collections.Generic.HashSet<string> result = new System.Collections.Generic.HashSet<string>(items);
            destination.Names = result;
        }

        destination.AddExistingName = AnsiConsole.Confirm("Enter [green]AddExistingName[/]");
        if (destination.AddExistingName == true)
        {
            destination.ExistingName = AnsiConsole.Prompt(new TextPrompt<string?>("Enter [green]ExistingName[/]").AllowEmpty());
        }

        if (destination.AddExistingName == false)
        {
            destination.NewName = AnsiConsole.Prompt(new TextPrompt<string?>("Enter [green]NewName[/]").AllowEmpty());
        }

        return destination;
    }
}

鸣谢

Smashicons 创作的恐惧图标 - Flaticon

在此包中没有受支持的框架资源。

有关更多关于 目标框架.NET Standard 的信息。

NuGet 包

此包没有被任何 NuGet 包使用。

GitHub 存储库

此包没有被任何流行的 GitHub 存储库使用。

版本 下载 最后更新
0.9.0 106 7/2/2024
0.9.0-preview-0.6 51 7/1/2024
0.8.2 79 6/25/2024
0.8.2-preview-01 68 6/23/2024
0.8.1 120 2/5/2024
0.8.0 190 11/30/2023
0.8.0-preview.0.1 99 11/4/2023
0.7.0 264 10/3/2023
0.7.0-preview.0.8 78 10/2/2023
0.7.0-preview.0.7 61 10/2/2023
0.7.0-preview.0.6 68 10/1/2023
0.7.0-preview.0.5 70 9/26/2023
0.7.0-preview.0.4.2 64 9/20/2023
0.7.0-preview.0.3 51 9/18/2023
0.7.0-preview.0.2 70 9/15/2023
0.7.0-preview.0.1 81 9/14/2023
0.6.0 298 9/12/2023
0.6.0-preview.0.4 71 9/10/2023
0.6.0-preview.0.1 66 9/3/2023
0.5.3 280 8/28/2023
0.5.2 281 8/27/2023
0.5.1 274 8/25/2023
0.5.0 297 8/23/2023
0.4.0 314 8/15/2023
0.3.8 322 8/6/2023
0.3.7.2 191 7/29/2023
0.3.6.1 187 7/25/2023
0.3.5 153 7/24/2023
0.3.4 175 7/23/2023
0.3.3 162 7/23/2023
0.3.2 328 1/22/2023
0.3.1 339 1/16/2023
0.3.0 340 1/6/2023
0.2.0.2 330 12/14/2022
0.2.0.1 306 12/14/2022
0.1.6 367 12/2/2022
0.1.5 345 11/30/2022

添加了 EnsureSearch 功能。开始弃用与 Dump 相关的扩展方法。改进了嵌套类支持