clawless_core/prompt/select.rs
1use getset::Getters;
2
3/// A question that a user answers with one of several options
4///
5/// The options are the texts that the user sees, in the order of display. The answer is the
6/// position of one option, and the first option has the position zero.
7///
8/// [`Prompt::select`] builds this type from the `Display` text of its options and sends it to
9/// the presenter. A command does not usually build it.
10///
11/// # Examples
12///
13/// ```
14/// use clawless_core::prompt::Select;
15///
16/// let question = Select::new("Kind of change", ["Added", "Changed", "Fixed"]);
17///
18/// assert_eq!(question.options().len(), 3);
19/// ```
20///
21/// [`Prompt::select`]: super::Prompt::select
22#[derive(Clone, Eq, PartialEq, Hash, Debug, Getters)]
23pub struct Select {
24 /// The text of the question
25 #[getset(get = "pub")]
26 question: String,
27
28 /// The texts of the options, in the order in which they are shown
29 #[getset(get = "pub")]
30 options: Vec<String>,
31}
32
33impl Select {
34 /// Creates a question over the texts of its options
35 ///
36 /// # Examples
37 ///
38 /// ```
39 /// use clawless_core::prompt::Select;
40 ///
41 /// let question = Select::new("Kind of change", ["Added", "Changed", "Fixed"]);
42 /// ```
43 pub fn new(
44 question: impl Into<String>,
45 options: impl IntoIterator<Item = impl Into<String>>,
46 ) -> Self {
47 Self {
48 question: question.into(),
49 options: options.into_iter().map(Into::into).collect(),
50 }
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 // An assertion in a test panics by design. A `# Panics` section on every test
57 // would repeat that and give the reader no information.
58 #![allow(clippy::missing_panics_doc)]
59
60 use super::*;
61
62 #[test]
63 fn new_keeps_the_options_in_their_order() {
64 let question = Select::new("Kind of change", ["Added", "Fixed"]);
65
66 assert_eq!(
67 question.options(),
68 &vec!["Added".to_owned(), "Fixed".to_owned()]
69 );
70 }
71
72 #[test]
73 fn trait_send() {
74 fn assert_send<T: Send>() {}
75 assert_send::<Select>();
76 }
77
78 #[test]
79 fn trait_sync() {
80 fn assert_sync<T: Sync>() {}
81 assert_sync::<Select>();
82 }
83
84 #[test]
85 fn trait_unpin() {
86 fn assert_unpin<T: Unpin>() {}
87 assert_unpin::<Select>();
88 }
89}