aboutsummaryrefslogtreecommitdiffstats
path: root/src/finder.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/finder.rs')
-rw-r--r--src/finder.rs93
1 files changed, 65 insertions, 28 deletions
diff --git a/src/finder.rs b/src/finder.rs
index db92c83..c5b5bd5 100644
--- a/src/finder.rs
+++ b/src/finder.rs
@@ -1,8 +1,9 @@
+use figment::Provider;
use std::{
+ ffi::OsStr,
io::Write,
ops::{Deref, DerefMut},
os::unix::prelude::OsStrExt,
- path::PathBuf,
process::{Child, Command, Output, Stdio},
};
@@ -12,41 +13,57 @@ pub use error::{Error, Result};
mod config;
mod error;
-pub struct Finder(Child);
+pub struct Finder {
+ program: String,
+ args: Vec<String>,
+}
impl Finder {
- pub fn new(config: &Config) -> Result<Self> {
- Command::new(&config.program)
- .args(&config.args)
+ pub fn new() -> Result<Self> {
+ Self::from_provider(Config::figment())
+ }
+
+ /// Extract `Config` from `provider` to construct new `Finder`
+ pub fn from_provider<T: Provider>(provider: T) -> Result<Self> {
+ Config::extract(&provider)
+ .map(|config| Finder {
+ program: config.program,
+ args: config.args,
+ })
+ .map_err(Into::into)
+ }
+
+ pub fn spawn(self) -> Result<FinderChild> {
+ Command::new(self.program)
+ .args(self.args)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
- .map(Into::into)
+ .map(FinderChild)
.map_err(Into::into)
}
+}
- pub fn into_inner(self) -> Child {
- self.0
- }
+pub struct FinderChild(Child);
- pub fn write_path_buf_vectored<V>(&mut self, directories: V) -> Result<()>
+impl FinderChild {
+ pub fn find<V, I>(mut self, items: V) -> Result<Output>
where
- V: IntoIterator<Item = PathBuf>,
+ V: IntoIterator<Item = I>,
+ I: AsRef<OsStr>,
{
let stdin = self.stdin.as_mut().ok_or(Error::Stdin)?;
- directories.into_iter().try_for_each(|path_buf| {
- stdin
- .write_all(path_buf.into_os_string().as_bytes())
- .map_err(From::from)
- })
- }
- pub fn wait_with_output(self) -> Result<Output> {
- self.into_inner().wait_with_output().map_err(From::from)
+ items.into_iter().try_for_each(|item| -> Result<()> {
+ stdin.write_all(item.as_ref().as_bytes())?;
+ stdin.write_all("\n".as_bytes()).map_err(From::from)
+ })?;
+
+ self.0.wait_with_output().map_err(Into::into)
}
}
-impl Deref for Finder {
+impl Deref for FinderChild {
type Target = Child;
fn deref(&self) -> &Self::Target {
@@ -54,20 +71,40 @@ impl Deref for Finder {
}
}
-impl DerefMut for Finder {
+impl DerefMut for FinderChild {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
-impl From<Child> for Finder {
- fn from(value: Child) -> Self {
- Self(value)
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_output() {
+ let items = Vec::from(["item1"]);
+
+ let finder = Finder {
+ program: "fzf".into(),
+ args: ["-1".into()].into(),
+ };
+
+ let selected = finder.spawn().unwrap().find(items).unwrap().stdout;
+ assert_eq!(selected.as_slice(), "item1\n".as_bytes())
}
-}
-impl From<Finder> for Child {
- fn from(value: Finder) -> Child {
- value.0
+ #[test]
+ #[ignore]
+ fn test_selection() {
+ let items = Vec::from(["item1", "item2", "item3", "item4"]);
+
+ let finder = Finder {
+ program: "fzf".into(),
+ args: [].into(),
+ };
+
+ let selected = finder.spawn().unwrap().find(items).unwrap().stdout;
+ assert_eq!(selected.as_slice(), "item1\n".as_bytes())
}
}