Repository: rust-lang/rustlings
File: src/list/state.rs (Rust)

Code before:
        write!(
            self.message,
            "The exercise `{exercise_name}` has been reset",
        )?;

        Ok(())
    }

    pub fn select_if_matches_search_query(&mut self) {
        let idx = self
            .app_state
            .exercises()
            .iter()
            .filter(|exercise| match self.filter() {
                Filter::None => true,
                Filter::Done => exercise.done,
                Filter::Pending => !exercise.done,
            })
            .enumerate()
            .find_map(|(i, s)| {
                if s.name.contains(self.search_query.as_str()) {
                    Some(i)
                } else {
                    None
                }
            });

        match idx {
            Some(i) => {
                let exercise_ind = i;
                self.scroll_state.set_selected(exercise_ind);
                self.update_rows();
            }
            None => {
                let msg = String::from("[NOT FOUND]") + &self.message.clone();
                self.message.clear();
                self.message.push_str(&msg);
            }
        }
    }

    // Return `true` if there was something to select.
    pub fn selected_to_current_exercise(&mut self) -> Result<bool> {
        let Some(selected) = self.scroll_state.selected() else {
            self.message.push_str("Nothing selected to continue at!");
            return Ok(false);
        };

        let exercise_ind = self.selected_to_exercise_ind(selected)?;
        self.app_state.set_current_exercise_ind(exercise_ind)?;


Review comment (suggestion):
Please use [`position`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.position) instead of `enumerate` with `find_map`.

I also try to avoid such short variable names. Better use `exercise` instead of `s`.

Code after:
        write!(
            self.message,
            "The exercise `{exercise_name}` has been reset",
        )?;

        Ok(())
    }

    pub fn apply_search_query(&mut self) {
        self.message.push_str("search:");
        self.message.push_str(&self.search_query);
        self.message.push('|');

        if self.search_query.is_empty() {
            return;
        }

        let idx = self
            .app_state
            .exercises()
            .iter()
            .filter(|exercise| match self.filter() {
                Filter::None => true,
                Filter::Done => exercise.done,
                Filter::Pending => !exercise.done,
            })
            .position(|exercise| exercise.name.contains(self.search_query.as_str()));

        match idx {
            Some(exercise_ind) => {
                self.scroll_state.set_selected(exercise_ind);
            }
            None => {
                let msg = String::from(" (not found)");
                self.message.push_str(&msg);
            }
        }
    }

    // Return `true` if there was something to select.
    pub fn selected_to_current_exercise(&mut self) -> Result<bool> {
        let Some(selected) = self.scroll_state.selected() else {
            self.message.push_str("Nothing selected to continue at!");
            return Ok(false);
        };

        let exercise_ind = self.selected_to_exercise_ind(selected)?;
        self.app_state.set_current_exercise_ind(exercise_ind)?;

        Ok(true)
    }