A file-based task manager
1use crate::errors::{Error, Result};
2use std::fmt::Display;
3use std::io::Write;
4use std::process::{Command, Stdio};
5use std::str::FromStr;
6
7/// Sends each item as a line to stdin to the `fzf` command and returns the selected item's string
8/// representation as output
9pub fn select<I>(input: impl IntoIterator<Item = I>) -> Result<Option<I>>
10where
11 I: Display + FromStr,
12 Error: From<<I as FromStr>::Err>,
13{
14 let mut child = Command::new("fzf")
15 .args(["-d", "\t"])
16 .stderr(Stdio::inherit())
17 .stdin(Stdio::piped())
18 .stdout(Stdio::piped())
19 .spawn()?;
20 // unwrap: this can never fail
21 let child_in = child.stdin.as_mut().unwrap();
22 for item in input.into_iter() {
23 write!(child_in, "{}\n", item.to_string())?;
24 }
25 let output = child.wait_with_output()?;
26 if output.stdout.is_empty() {
27 Ok(None)
28 } else {
29 Ok(Some(String::from_utf8(output.stdout)?.parse()?))
30 }
31}