use std::{cmp, fmt, process};
enum Answer {
Percentage(u8),
Text(String),
}
impl fmt::Display for Answer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Percentage(pc) => write!(f, "{}%", cmp::min(100, *pc)),
Self::Text(txt) => write!(f, "{}", txt),
}
}
}
trait Query {
fn ask(&mut self) -> Answer;
fn been_asked(&self) -> bool;
}
struct CommandQueryTemplate {
path: String,
args: Vec<String>,
asked: bool,
}
impl Query for CommandQueryTemplate {
fn ask(&mut self) -> Answer {
let ans = process::Command::new(&self.path)
.args(&self.args)
.output()
.expect("failed");
self.asked = true;
Answer::Text(String::from_utf8_lossy(&ans.stdout).to_string())
}
fn been_asked(&self) -> bool {
self.asked
}
}
mod tests {
#[test]
fn answer_percentage_display() {
use super::Answer;
let under_100 = Answer::Percentage(5);
let over_100 = Answer::Percentage(105);
assert_eq!("5%".to_string(), under_100.to_string());
assert_eq!("100%".to_string(), over_100.to_string());
}
#[test]
fn command_template_basic() {
use super::{CommandQueryTemplate, Query};
let mut query = CommandQueryTemplate {
path: "/usr/bin/echo".to_string(),
args: vec!["hello".to_string()],
asked: false,
};
let ans = query.ask();
assert_eq!("hello\n".to_string(), ans.to_string());
}
}