QuestionBuilder

Struct QuestionBuilder 

Source
pub struct QuestionBuilder<T, R, W> { /* private fields */ }
Expand description

Async I/O handler (in builder form).

§Contents

§Processing

There are many steps in handling input and giving feedback, and therefore many options. As a preview, these are the main steps:

  1. Write message
  2. Take input
  3. Test the input as a String
  4. Parse input
  5. Test the value
  6. Give feedback
  7. Return the value

For more details, checkout the ask method.

Implementations§

Source§

impl<T, R, W> QuestionBuilder<T, R, W>
where R: Read, W: Write,

§Constructor

Source

pub fn new<F, E>(reader: R, writer: W, parser: F) -> Self
where F: Fn(&str) -> Result<T, E> + Send + Sync + 'static, E: Error + Send + Sync + 'static,

Constructs a new QuestionBuilder<T, R, W>.

§Remarks

There are two default behaviours while handling strings.

  1. The preparser trims the end of the input.
  2. The error_formatter adds a new line before display.
Source§

impl<T, R, W> QuestionBuilder<T, R, W>
where T: FromStr, <T as FromStr>::Err: Error + Send + Sync + 'static, R: Read, W: Write,

Source

pub fn new_fromstr(reader: R, writer: W) -> Self

Constructs a new QuestionBuilder<T, R, W> where the parser is given by the implementation of FromStr.

Source§

impl<T, R, W> QuestionBuilder<T, R, W>

§Message

Main messages that will be displayed.

Source

pub fn message(self, message: impl ToString) -> Self

Message to be displayed.

Source

pub fn repeat_message(self, message: impl ToString) -> Self

Message to be displayed repeatedly before each attempt.

Source

pub fn help(self, help: impl ToString) -> Self

Help message to be displayed after the first failed attempt.

Source

pub fn repeat_help(self, help: impl ToString) -> Self

Help message to be displayed every time an attempt failed.

Source

pub fn feedback<F>(self, feedback: F) -> Self
where F: Fn(&T) -> String + Send + Sync + 'static,

Feedback message to be displayed after the input has been succesfully processed.

Source§

impl<T, R, W> QuestionBuilder<T, R, W>

§Testing value

We encourage to write tests whose error should be displayed to the user, and add them with the test_with_msg method.

Source

pub fn clear(self) -> Self

Forgets all tests.

Source

pub fn test<F>(self, test: F) -> Self
where F: Fn(&T) -> bool + Send + Sync + 'static,

Add a new test for the value.

§Remarks

There is a default message you might want to change.

Source

pub fn test_with_msg<F, M>(self, test: F, message: M) -> Self
where F: Fn(&T) -> bool + Send + Sync + 'static, M: ToString + Send + Sync + 'static,

Add a new test for the value, displaying a message upon failure.

Source§

impl<T, R, W> QuestionBuilder<T, R, W>
where T: PartialEq + PartialOrd + Send + Sync + 'static,

§Testing value extended

§Remarks

Not all bounds are used in all methods. Open an issue in GitHub if this is a problem for you.

Source

pub fn inside<I>(self, iterator: I) -> Self
where I: IntoIterator<Item = T> + 'static,

Test if the value is inside an iterator.

§Remarks

To prevent infinite loops, make sure iterator is finite. Also, there is a default message you might want to change.

Source

pub fn inside_with_msg<I, M>(self, iterator: I, message: M) -> Self
where I: IntoIterator<Item = T> + 'static, M: ToString + Send + Sync + 'static,

Test if the value is inside an iterator, displaying a message upon failure.

§Remarks

To prevent infinite loops, make sure iterator is finite.

Source

pub fn max(self, upper_bound: T) -> Self

Test if the value is at most upper_bound.

§Remarks

There is a default message you might want to change.

Source

pub fn max_with_msg<M>(self, upper_bound: T, message: M) -> Self
where M: ToString + Send + Sync + 'static,

Test if the value is at most upper_bound, displaying a message upon failure.

Source

pub fn min_max(self, lower_bound: T, upper_bound: T) -> Self

Test if the value is between lower_bound and upper_bound, including borders.

§Remarks

There is a default message you might want to change.

Source

pub fn min_max_with_msg<M>( self, lower_bound: T, upper_bound: T, message: M, ) -> Self
where M: ToString + Send + Sync + 'static,

Test if the value is between lower_bound and upper_bound, including borders, displaying a message upon failure.

Source

pub fn min(self, lower_bound: T) -> Self

Test if the value is at least lower_bound.

§Remarks

There is a default message you might want to change.

Source

pub fn min_with_msg<M>(self, lower_bound: T, message: M) -> Self
where M: ToString + Send + Sync + 'static,

Test if the value is at least lower_bound, displaying a message upon failure.

Source

pub fn not(self, other: T) -> Self

Test if the value is not other.

§Remarks

There is a default message you might want to change.

Source

pub fn not_with_msg<M>(self, other: T, message: M) -> Self
where M: ToString + Send + Sync + 'static,

Test if the value is not other, displaying a message upon failure.

Source§

impl<T, R, W> QuestionBuilder<T, R, W>

§Useful settings

Source

pub fn attempts<O>(self, attempts: O) -> Self
where O: Into<Option<usize>>,

Bound the number of possible attempts.

The default value is None, which gives infinite attempts to the user.

Source

pub fn attempts_with_feedback<F>(self, attempts: usize, feedback: F) -> Self
where F: Fn(usize) -> String + Send + Sync + 'static,

Bound the number of possible attempts, displaying a message before any input is read.

The default value is None, which gives infinite attempts to the user.

§Remarks

Before the first attempt, a message will be displayed, so make sure to handle that case.

Source

pub fn default_value<S>(self, value: S) -> Self
where S: Into<Option<T>>,

Give a default value in case the input is not required and empty.

§Remarks

Default values are NOT tested, so make sure that it is a value that passes your tests!

Source

pub fn required(self) -> Self

Requires that the input is not empty to continue.

§Remarks

There is a default message you might want to change.

Source

pub fn required_with_msg(self, message: impl ToString) -> Self

Requires that the input is not empty to continue, displaying a message upon failure.

Source

pub fn required_toogle(self) -> Self

Toggles between requiring and not requiring input.

Source§

impl<T, R, W> QuestionBuilder<T, R, W>

§Executors

For ease of use, there are some built-in executors.

Source

pub fn timeout(self, duration: Duration) -> Self

Set a maximum time for the user to finish answering the question.

§Remarks

This time corresponds to the whole execution, including displaying feedback. So the user might enter valid input before the time runs out, but the whole process might still timeout.

Source§

impl<T, R, W> QuestionBuilder<T, R, W>
where W: Write + Unpin, R: Read + Unpin,

§Prompt functionalities

Source

pub async fn ask(self) -> Result<T, Processing>

Asynchronously gets input from the user.

The detailed process is as follows.

  1. Check there are attempts left
  2. Write message
  3. Write feedback from attempts
  4. Read input
  5. Apply the preparser to the input
  6. Return default_value if it corresponds
  7. Apply all str_tests
  8. Convert the input with parser
  9. Apply all tests
  10. Write feedback
  11. Return the value
§Remarks

There are two types of messages that can be displayed during the process: feedback and error messages. Feedback is displayed as given by the corresponding method. Error messages are displayed after applying error_formatter.

More over, error messages are displayed through the eyre crate. Therefore, you can further configure their display (check out EyreHandler). error_formatter is applied on top of displaying the error.

Source

pub fn ask_and_wait(self) -> Result<T, Processing>

Synchronously gets input from the user.

Convenience method for async_std::task::block_on(self.ask()).

§Remarks

Although this method goes against the goal of this crate, it is useful for quick implementations.

Source§

impl<T, R, W> QuestionBuilder<T, R, W>

§Processing text input

§Remarks

This is done after applying the preparser and before parsing the input. Therefore, the changes the preparser process (like triming trailing space) do not count for the length of the input.

Source

pub fn preparser<F>(self, preparser: F) -> Self
where F: Fn(String) -> String + Send + Sync + 'static,

Set the preparser for the input.

This is applied to the raw input before being parsed to T. In CLI applications, it is useful to clean the leading new line that comes with the input.

Source

pub fn str_test<F>(self, str_test: F) -> Self
where F: Fn(&str) -> bool + Send + Sync + 'static,

Add a test over the unparsed input.

§Remarks

There is a default message that you might want to change.

Source

pub fn str_test_with_msg<F, M>(self, str_test: F, message: M) -> Self
where F: Fn(&str) -> bool + Send + Sync + 'static, M: ToString + Send + Sync + 'static,

Add a test over the unparsed input, displaying a message upon failure.

Source

pub fn length(self, exact_length: usize) -> Self

Tests that the input length is equal to exact_length.

§Remarks

There is a default message that you might want to change.

Source

pub fn length_with_msg<M>(self, exact_length: usize, message: M) -> Self
where M: ToString + Send + Sync + 'static,

Tests that the input length is equal to exact_length, displaying a message upon failure.

Source

pub fn max_length(self, max_length: usize) -> Self

Tests that the input length is less or equal to max_length.

§Remarks

There is a default message that you might want to change.

Source

pub fn max_length_with_msg<M>(self, max_length: usize, message: M) -> Self
where M: ToString + Send + Sync + 'static,

Tests that the input length is less or equal to max_length, displaying a message upon failure.

Source

pub fn min_length(self, min_length: usize) -> Self

Tests that the input length is greater or equal to min_length.

§Remarks

There is a default message that you might want to change.

Source

pub fn min_length_with_msg<M>(self, min_length: usize, message: M) -> Self
where M: ToString + Send + Sync + 'static,

Tests that the input length is greater or equal to min_length, displaying a message upon failure.

Source

pub fn parser<F>(self, parser: F) -> Self
where F: Fn(&str) -> Result<T> + Send + Sync + 'static,

Set the parser for the input.

§Remarks

Errors will NOT be displayed if they occur. Check out parser_with_feedback if you want to display a message upon failure.

Source§

impl<T, R, W> QuestionBuilder<T, R, W>

§Advanced methods

Source

pub fn reader<R2: Read>(self, other_reader: R2) -> QuestionBuilder<T, R2, W>

Change the reader.

Source

pub fn writer<W2: Write>(self, other_writer: W2) -> QuestionBuilder<T, R, W2>

Change the writer.

Source

pub fn error_formatter<F>(self, error_formatter: F) -> Self
where F: Fn(String) -> String + Send + Sync + 'static,

Change the way errors are displayed.

§Remarks

This can be useful if to:

  • Change the default behaviour of appending a newline.
  • Not display a message upon an error.
§Examples

Silent errors. Now, only messages will be displayed.

    let _num = asking::question()
        .message("Give me a number bigger than 3, please. I will not tell you anything else.\n")
        .test(|i: &u32| *i > 3)
        .error_formatter(|_| "".to_string())
        .ask()
        .await?;
Source

pub fn parser_feedback_toggle(self) -> Self

Toggle the feedback from the parser.

If activated, errors from parsing will be displayed.

Source

pub fn parser_with_feedback<F>(self, parser: F) -> Self
where F: Fn(&str) -> Result<T> + Send + Sync + 'static,

Set the parser for the input.

Errors will be displayed if they occur.

Source

pub fn str_test_with_feedback<F>(self, str_test: F) -> Self
where F: Fn(&str) -> Result<()> + Send + Sync + 'static,

Add a test over the unparsed input.

Errors will be displayed if they occur.

Source

pub fn test_with_feedback<F>(self, test: F) -> Self
where F: Fn(&T) -> Result<()> + Send + Sync + 'static,

Add a test over the parsed input

Errors will be displayed if they occur.

Trait Implementations§

Source§

impl<T, R, W> Debug for QuestionBuilder<T, R, W>
where T: Debug, R: Read + Debug, W: Write + Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T, R, W> Freeze for QuestionBuilder<T, R, W>
where R: Freeze, W: Freeze, T: Freeze,

§

impl<T, R, W> !RefUnwindSafe for QuestionBuilder<T, R, W>

§

impl<T, R, W> Send for QuestionBuilder<T, R, W>
where R: Send, W: Send, T: Send,

§

impl<T, R, W> Sync for QuestionBuilder<T, R, W>
where R: Sync, W: Sync, T: Sync,

§

impl<T, R, W> Unpin for QuestionBuilder<T, R, W>
where T: Unpin, R: Unpin, W: Unpin,

§

impl<T, R, W> !UnwindSafe for QuestionBuilder<T, R, W>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.