basic/
basic.rs

1use std::io::stdout;
2
3use tty_form::{
4    control::{Control, SelectInput, StaticText, TextInput},
5    dependency::{Action, Evaluation},
6    device::StdinDevice,
7    step::{CompoundStep, KeyValueStep, Step, TextBlockStep, YesNoStep},
8    Error, Form, Result,
9};
10use tty_interface::Interface;
11
12fn main() {
13    let result = execute().expect("executes basic example");
14    println!("Result:");
15    println!("{}", result);
16    println!("Done.");
17}
18
19fn execute() -> Result<String> {
20    let mut form = Form::new();
21
22    let mut commit_summary = CompoundStep::new();
23    commit_summary.set_max_line_length(80);
24
25    SelectInput::new(
26        "Select the commit type.",
27        vec![
28            ("feat", "implemented a new feature"),
29            ("bug", "fixed existing behavior"),
30            ("docs", "added documentation"),
31            ("chore", "non-source changes"),
32        ],
33    )
34    .add_to(&mut commit_summary);
35
36    let mut opening_paren = StaticText::new("(");
37    let mut closing_paren = StaticText::new(")");
38
39    let mut scope_input = TextInput::new("Enter the commit's scope.", true);
40
41    let empty_scope = scope_input.set_evaluation(Evaluation::IsEmpty);
42    opening_paren.set_dependency(empty_scope, Action::Hide);
43    closing_paren.set_dependency(empty_scope, Action::Hide);
44
45    let mut breaking_bang = StaticText::new("!");
46    let colon = StaticText::new(": ");
47
48    let description = TextInput::new("Enter the commit's description.", true);
49
50    let mut long_description = TextBlockStep::new("Enter a long-form commit description.");
51    long_description.set_margins(Some(1), Some(1));
52    long_description.set_max_line_length(100);
53
54    let mut breaking_step = YesNoStep::new(
55        "Is this commit a breaking change?",
56        "Enter a description of the breaking change.",
57        "BREAKING CHANGE",
58    );
59
60    let trailers = KeyValueStep::new("Enter any key-value trailers, such as tickets.");
61
62    let breaking_change = breaking_step.set_evaluation(Evaluation::Equal("Yes".to_string()));
63    breaking_bang.set_dependency(breaking_change, Action::Show);
64
65    opening_paren.add_to(&mut commit_summary);
66    scope_input.add_to(&mut commit_summary);
67    closing_paren.add_to(&mut commit_summary);
68    breaking_bang.add_to(&mut commit_summary);
69    colon.add_to(&mut commit_summary);
70    description.add_to(&mut commit_summary);
71    commit_summary.add_to(&mut form);
72    long_description.add_to(&mut form);
73    trailers.add_to(&mut form);
74    breaking_step.add_to(&mut form);
75
76    let mut stdout = stdout();
77    let mut stdin = StdinDevice;
78
79    let mut interface = Interface::new_relative(&mut stdout)?;
80
81    let result = form.execute(&mut interface, &mut stdin);
82    interface.exit()?;
83
84    let mut output = String::new();
85    match result {
86        Ok(value) => output = value,
87        Err(Error::Canceled) => println!("Form canceled."),
88        Err(err) => eprintln!("Unexpected error occurred: {:?}", err),
89    }
90
91    Ok(output)
92}