sauce/cli/
utilities.rs

1use anyhow::{anyhow, Result};
2use std::io::Read;
3use std::str::FromStr;
4
5/// Parse a single key-value pair
6pub fn parse_key_val<T: FromStr>(s: &str) -> Result<(T, T)>
7where
8    <T as FromStr>::Err: std::error::Error + Send + Sync + 'static,
9{
10    let mut iter = s.splitn(2, '=');
11    let first = iter.next();
12    let second = iter.next();
13    match (first, second) {
14        (Some(first), Some(second)) => Ok((first.parse()?, second.parse()?)),
15        _ => Err(anyhow!("Invalid KEY=value: no `=` found in `{}`", s)),
16    }
17}
18
19/// Accept data from stdin
20pub fn get_input(values: &[(String, String)]) -> Vec<(String, String)> {
21    let mut result = Vec::new();
22    result.extend_from_slice(values);
23
24    let mut buffer = String::new();
25
26    if atty::isnt(atty::Stream::Stdin) {
27        std::io::stdin()
28            .read_to_string(&mut buffer)
29            .expect("Could not read stdin");
30
31        if !buffer.is_empty() {
32            if let Some(b) = buffer.strip_suffix('\n') {
33                buffer = b.to_string();
34            }
35
36            if let Ok(keyval) = parse_key_val(&buffer) {
37                result.push(keyval);
38            }
39        }
40    }
41
42    result
43}
44
45#[cfg(test)]
46mod tests {
47    mod parse_key_val {
48        use super::super::*;
49        use pretty_assertions::assert_eq;
50
51        #[test]
52        fn it_works_with_one_equals() {
53            let (key, value): (String, String) = parse_key_val("meow=bar").unwrap();
54            assert_eq!(key, "meow".to_string());
55            assert_eq!(value, "bar".to_string());
56        }
57
58        #[test]
59        fn it_works_with_2_plus_equals() {
60            let (key, value): (String, String) = parse_key_val("meow=bar=bar2=bar3").unwrap();
61            assert_eq!(key, "meow".to_string());
62            assert_eq!(value, "bar=bar2=bar3".to_string());
63        }
64
65        #[test]
66        fn it_fails() {
67            let result: Result<(String, String)> = parse_key_val("meow");
68            let error = result.err().unwrap();
69            assert_eq!(
70                format!("{}", error),
71                "Invalid KEY=value: no `=` found in `meow`".to_string()
72            );
73        }
74    }
75}