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