From 0d6a70bd0f93f10a493f4c99aaab2d02ddcb8ad3 Mon Sep 17 00:00:00 2001 From: seb-bl <31244011+seb-bl@users.noreply.github.com> Date: Sun, 10 May 2020 10:44:24 +0200 Subject: [PATCH] Interface::run returns a Cow<'a> Changed `Interface::run` to return a `Cow` with the lifetime of the borrowed slice of strings. The `Owned` case occurs when the search does not match anything. In that case, the search string is taken out of the `Interface` and replaced by an empty string. Using a `Cow` with the lifetime of the given strings allows to drop the `Interface` struct after a run, without needing to clone the returned `&str` to keep the result. It also allows the caller to know whether the result is from the given list, or comes from a search that had no match. --- src/interface.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/interface.rs b/src/interface.rs index eea8c86..153733a 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::io::{self, Write, BufWriter}; use super::{MatchWithPositions, match_and_score_with_positions}; @@ -57,8 +58,9 @@ impl<'a> Interface<'a> { } } - // Runs the Interface, returning either the final selection, or an error - pub fn run(&mut self) -> Result<&str, Error> { + // Runs the Interface, returning either the final selection, the final + // search string if nothing matches, or an error + pub fn run(&mut self) -> Result, Error> { self.filter_matches(); self.render()?; @@ -108,7 +110,7 @@ impl<'a> Interface<'a> { } self.reset()?; - Ok(self.result()) + Ok(self.take_result()) } // Matches and scores `lines` by `search`, sorting the result @@ -205,10 +207,13 @@ impl<'a> Interface<'a> { Ok(()) } - fn result(&mut self) -> &str { + // Get a reference to the selected item, or take the search (and replace it with empty) + fn take_result(&mut self) -> Cow<'a, str> { self.matches.iter(). nth(self.selected). - map(|choice| choice.0). - unwrap_or(&self.search) + map(|choice| Cow::Borrowed(choice.0)). + unwrap_or_else(|| + Cow::Owned(std::mem::take(&mut self.search)) + ) } }