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}