cli/util/
input.rs

1/*---------------------------------------------------------------------------------------------
2 *  Copyright (c) Microsoft Corporation. All rights reserved.
3 *  Licensed under the MIT License. See License.txt in the project root for license information.
4 *--------------------------------------------------------------------------------------------*/
5use crate::util::errors::wrap;
6use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
7use indicatif::ProgressBar;
8use std::fmt::Display;
9
10use super::{errors::WrappedError, io::ReportCopyProgress};
11
12/// Wrapper around indicatif::ProgressBar that implements ReportCopyProgress.
13pub struct ProgressBarReporter {
14	bar: ProgressBar,
15	has_set_total: bool,
16}
17
18impl From<ProgressBar> for ProgressBarReporter {
19	fn from(bar: ProgressBar) -> Self {
20		ProgressBarReporter {
21			bar,
22			has_set_total: false,
23		}
24	}
25}
26
27impl ReportCopyProgress for ProgressBarReporter {
28	fn report_progress(&mut self, bytes_so_far: u64, total_bytes: u64) {
29		if !self.has_set_total {
30			self.bar.set_length(total_bytes);
31		}
32
33		if bytes_so_far == total_bytes {
34			self.bar.finish_and_clear();
35		} else {
36			self.bar.set_position(bytes_so_far);
37		}
38	}
39}
40
41pub fn prompt_yn(text: &str) -> Result<bool, WrappedError> {
42	Confirm::with_theme(&ColorfulTheme::default())
43		.with_prompt(text)
44		.default(true)
45		.interact()
46		.map_err(|e| wrap(e, "Failed to read confirm input"))
47}
48
49pub fn prompt_options<T>(text: impl Into<String>, options: &[T]) -> Result<T, WrappedError>
50where
51	T: Display + Copy,
52{
53	let chosen = Select::with_theme(&ColorfulTheme::default())
54		.with_prompt(text)
55		.items(options)
56		.default(0)
57		.interact()
58		.map_err(|e| wrap(e, "Failed to read select input"))?;
59
60	Ok(options[chosen])
61}
62
63pub fn prompt_placeholder(question: &str, placeholder: &str) -> Result<String, WrappedError> {
64	Input::with_theme(&ColorfulTheme::default())
65		.with_prompt(question)
66		.default(placeholder.to_string())
67		.interact_text()
68		.map_err(|e| wrap(e, "Failed to read confirm input"))
69}