Skip to main content

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}