diff --git a/CHANGELOG.md b/CHANGELOG.md index d2f0d5d..9a5fdb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ## [Unreleased] +- Don't require static lifetime for autocompleter and validator. - Fix autocomplete suggestions not being updated after a suggestion is accepted. Thanks @moritz-hoelting and @istudyatuni for reporting and fixing it! - Fix incorrect cursor placement when inputting CJK characters. Thanks @phostann (#270) for reporting it! - Removed unused dependency (newline-converter). Thanks @jonassmedegaard (#267) for catching it! diff --git a/inquire/src/prompts/text/config.rs b/inquire/src/prompts/text/config.rs index d0b84fa..fad2a75 100644 --- a/inquire/src/prompts/text/config.rs +++ b/inquire/src/prompts/text/config.rs @@ -7,8 +7,8 @@ pub struct TextConfig { pub page_size: usize, } -impl From<&Text<'_>> for TextConfig { - fn from(value: &Text<'_>) -> Self { +impl From<&Text<'_, '_>> for TextConfig { + fn from(value: &Text<'_, '_>) -> Self { Self { page_size: value.page_size, } diff --git a/inquire/src/prompts/text/mod.rs b/inquire/src/prompts/text/mod.rs index aeda72d..1ddd26b 100644 --- a/inquire/src/prompts/text/mod.rs +++ b/inquire/src/prompts/text/mod.rs @@ -73,8 +73,7 @@ const DEFAULT_HELP_MESSAGE_WITH_AC: &str = "↑↓ to move, tab to autocomplete, /// Err(_) => println!("An error happened when asking for your name, try again later."), /// } /// ``` -#[derive(Clone)] -pub struct Text<'a> { +pub struct Text<'a, 'b> { /// Message to be presented to the user. pub message: &'a str, @@ -98,7 +97,7 @@ pub struct Text<'a> { pub formatter: StringFormatter<'a>, /// Autocompleter responsible for handling suggestions and input completions. - pub autocompleter: Option>, + pub autocompleter: Option>, /// Collection of validators to apply to the user input. /// @@ -106,7 +105,7 @@ pub struct Text<'a> { /// only the first validation error that might appear. /// /// The possible error is displayed to the user one line above the prompt. - pub validators: Vec>, + pub validators: Vec>, /// Page size of the suggestions displayed to the user, when applicable. pub page_size: usize, @@ -122,7 +121,24 @@ pub struct Text<'a> { pub render_config: RenderConfig<'a>, } -impl<'a> Text<'a> { +impl<'a> Clone for Text<'a, 'static> { + fn clone(&self) -> Self { + Self { + message: self.message, + initial_value: self.initial_value, + default: self.default, + placeholder: self.placeholder, + help_message: self.help_message, + formatter: self.formatter, + autocompleter: self.autocompleter.clone(), + validators: self.validators.clone(), + page_size: self.page_size, + render_config: self.render_config, + } + } +} + +impl<'a, 'b> Text<'a, 'b> { /// Default formatter, set to [DEFAULT_STRING_FORMATTER](crate::formatter::DEFAULT_STRING_FORMATTER) pub const DEFAULT_FORMATTER: StringFormatter<'a> = DEFAULT_STRING_FORMATTER; @@ -182,7 +198,7 @@ impl<'a> Text<'a> { /// Sets a new autocompleter pub fn with_autocomplete(mut self, ac: AC) -> Self where - AC: Autocomplete + 'static, + AC: Autocomplete + 'b, { self.autocompleter = Some(Box::new(ac)); self @@ -210,7 +226,7 @@ impl<'a> Text<'a> { /// The possible error is displayed to the user one line above the prompt. pub fn with_validator(mut self, validator: V) -> Self where - V: StringValidator + 'static, + V: StringValidator + 'b, { self.validators.push(Box::new(validator)); self @@ -226,7 +242,6 @@ impl<'a> Text<'a> { /// The possible error is displayed to the user one line above the prompt. pub fn with_validators(mut self, validators: &[Box]) -> Self { for validator in validators { - #[allow(suspicious_double_ref_op)] self.validators.push(validator.clone()); } self diff --git a/inquire/src/prompts/text/prompt.rs b/inquire/src/prompts/text/prompt.rs index e0ae7ab..b5701a5 100644 --- a/inquire/src/prompts/text/prompt.rs +++ b/inquire/src/prompts/text/prompt.rs @@ -15,22 +15,22 @@ use crate::{ use super::{action::TextPromptAction, config::TextConfig, DEFAULT_HELP_MESSAGE_WITH_AC}; -pub struct TextPrompt<'a> { +pub struct TextPrompt<'a, 'b> { message: &'a str, config: TextConfig, default: Option<&'a str>, help_message: Option<&'a str>, input: Input, formatter: StringFormatter<'a>, - validators: Vec>, + validators: Vec>, error: Option, - autocompleter: Box, + autocompleter: Box, suggested_options: Vec, suggestion_cursor_index: Option, } -impl<'a> From> for TextPrompt<'a> { - fn from(so: Text<'a>) -> Self { +impl<'a, 'b> From> for TextPrompt<'a, 'b> { + fn from(so: Text<'a, 'b>) -> Self { let input = Input::new_with(so.initial_value.unwrap_or_default()); let input = if let Some(placeholder) = so.placeholder { input.with_placeholder(placeholder) @@ -56,13 +56,13 @@ impl<'a> From> for TextPrompt<'a> { } } -impl<'a> From<&'a str> for Text<'a> { +impl<'a, 'b> From<&'a str> for Text<'a, 'b> { fn from(val: &'a str) -> Self { Text::new(val) } } -impl<'a> TextPrompt<'a> { +impl<'a, 'b> TextPrompt<'a, 'b> { fn update_suggestions(&mut self) -> InquireResult<()> { self.suggested_options = self.autocompleter.get_suggestions(self.input.content())?; self.suggestion_cursor_index = None; @@ -161,7 +161,7 @@ impl<'a> TextPrompt<'a> { } } -impl<'a, Backend> Prompt for TextPrompt<'a> +impl<'a, 'b, Backend> Prompt for TextPrompt<'a, 'b> where Backend: TextBackend, { diff --git a/inquire/src/prompts/text/test.rs b/inquire/src/prompts/text/test.rs index 35d43e5..1705173 100644 --- a/inquire/src/prompts/text/test.rs +++ b/inquire/src/prompts/text/test.rs @@ -2,7 +2,7 @@ use super::Text; use crate::ui::{Key, KeyModifiers}; use crate::validator::{ErrorMessage, Validation}; -fn default<'a>() -> Text<'a> { +fn default<'a, 'b>() -> Text<'a, 'b> { Text::new("Question?") }