A file-based task manager
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at noah/git-backend-2 42 lines 1.2 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 // fzf appends a trailing newline; strip it so the FromStr impls 38 // (Id, String, usize, etc.) all work. 39 let raw = String::from_utf8(output.stdout)?; 40 Ok(Some(raw.trim().parse()?)) 41 } 42}