Commit feb95d12 authored by Alexandru Scvortov's avatar Alexandru Scvortov
Browse files

Support "yes" prompts

parent 9bf58f7b
0.2.0
=====
Add support for "yes" prompts.
0.1.0
=====
......
[package]
name = "challenge-prompt"
version = "0.1.0"
version = "0.2.0"
authors = ["Alexandru Scvortov <rust@abstractbinary.org>"]
license = "Apache-2.0"
readme = "README.md"
......
......@@ -23,7 +23,7 @@ Library example
Add this to your `Cargo.toml`:
[dependencies]
challenge-prompt = "0.1"
challenge-prompt = "0.2"
and this to your crate root:
......
......@@ -8,7 +8,8 @@
//! Available prompts are:
//! - arithmetic: Asks the user to solve a problem like `(12 + 7) mod 4`,
//! - phrase: Asks the user to type in a phrase like "I am probably making a
//! mistake" exactly.
//! mistake" exactly,
//! - yes: Asks the user to type in 'y' or 'yes'.
//!
//! This crate is both a library and a small command line application for use in
//! shell scripts.
......@@ -25,7 +26,7 @@
//!
//! ```toml
//! [dependencies]
//! challenge_prompt = "0.1"
//! challenge_prompt = "0.2"
//! ```
//!
//! ```no_run
......@@ -42,6 +43,7 @@ extern crate rand;
pub enum Challenge {
Arithmetic,
Phrase(String),
Yes,
}
pub const DEFAULT_PHRASE: &str = "I am probably making a mistake.";
......@@ -59,27 +61,28 @@ impl Challenge {
let c = rand::random::<u32>() % 18 + 2;
prompt_gen(
&format!("Solve: ({} + {}) mod {} = ?", a, b, c),
&format!("{}", (a + b) % c),
&[&format!("{}", (a + b) % c)],
)
}
Phrase(str) => prompt_gen(
&format!("Enter the following exactly to continue: {}", str),
str,
&[str],
),
Yes => prompt_gen("Continue? [y]", &["y", "yes"]),
}
}
}
/// Generic prompt implementation: print out the `prompt`, read a line of input,
/// and return whether it matches `expected` or not.
pub fn prompt_gen(prompt: &str, expected: &str) -> bool {
pub fn prompt_gen(prompt: &str, expected: &[&str]) -> bool {
use std::io;
println!("{}", prompt);
let mut input = String::new();
loop {
match io::stdin().read_line(&mut input) {
Ok(_) => return expected == input.trim(),
Err(_) => {}
if io::stdin().read_line(&mut input).is_ok() {
let input = input.trim();
return expected.iter().any(|&e| e == input);
}
}
}
......@@ -116,7 +119,7 @@ mod tests {
Command::main_binary()
.unwrap()
.with_stdin()
.buffer("100") // No prompt ever returns 100
.buffer("100") // No prompt ever returns 100
.assert()
.code(1);
}
......@@ -147,4 +150,42 @@ mod tests {
.assert()
.code(0);
}
#[test]
fn yes_no_challenge() {
Command::main_binary()
.unwrap()
.arg("-y")
.assert()
.stdout(predicate::str::contains("[y]").from_utf8())
.code(1);
Command::main_binary()
.unwrap()
.arg("-y")
.with_stdin()
.buffer("y")
.assert()
.code(0);
Command::main_binary()
.unwrap()
.arg("-y")
.with_stdin()
.buffer("yes")
.assert()
.code(0);
Command::main_binary()
.unwrap()
.arg("--yes")
.with_stdin()
.buffer("n")
.assert()
.code(1);
Command::main_binary()
.unwrap()
.arg("--yes")
.with_stdin()
.buffer("nooooo")
.assert()
.code(1);
}
}
......@@ -19,8 +19,8 @@ fn main() {
let args = parse_args();
match args {
Version => print_version(),
Help => print_usage(None),
UsageError(error) => print_usage(Some(error)),
Help => print_usage(&None),
UsageError(error) => print_usage(&Some(error)),
Challenge(chlg) => {
if chlg.prompt() {
std::process::exit(0);
......@@ -39,13 +39,13 @@ fn executable_name() -> String {
fn print_version() {
println!("{} {}", executable_name(), env!("CARGO_PKG_VERSION"));
println!("")
println!()
}
fn print_usage(error: Option<String>) {
fn print_usage(error: &Option<String>) {
error.iter().for_each(|error| {
println!("error: {}", error);
println!("")
println!()
});
print_version();
println!(
......@@ -59,6 +59,9 @@ OPTIONS:
-p, --phrase=STR
Prompt the user to type in exactly the given phrase.
-y, --yes
Prompt the user to type in 'y' or 'yes'.
--version
Print out version information.
......@@ -103,7 +106,6 @@ fn parse_args() -> Args {
return multiple_challenges_err(old_challenge, &Arithmetic)
}
},
"-h" | "--help" => return Help,
"-p" | "--phrase" => match challenge {
None => match next {
None => challenge = Some(Phrase(DEFAULT_PHRASE.to_owned())),
......@@ -119,6 +121,11 @@ fn parse_args() -> Args {
return multiple_challenges_err(old_challenge, &Phrase("".to_owned()))
}
},
"-y" | "--yes" => match challenge {
None => challenge = Some(Yes),
Some(ref old_challenge) => return multiple_challenges_err(old_challenge, &Yes),
},
"-h" | "--help" => return Help,
"-v" | "--version" => return Version,
s => return UsageError(format!("unknown option: {}", s)),
},
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment