Skip to main content

steel_core/command/execution/
suggestion_provider.rs

1//! *Suggestion providers* to provide custom suggestions for arguments when needed.
2
3use crate::command::brigadier::{
4    ArgumentSuggestionContext, CommandArgumentParser, SuggestionProvider, SuggestionsBuilder,
5};
6
7pub fn matches_suggestion_substring_case_sensitive(pattern: &str, input: &str) -> bool {
8    if input.starts_with(pattern) {
9        return true;
10    }
11    input.char_indices().any(|(index, character)| {
12        matches!(character, '.' | '_' | '/')
13            && input[index + character.len_utf8()..].starts_with(pattern)
14    })
15}
16
17pub fn matches_suggestion_substring(pattern: &str, input: &str) -> bool {
18    matches_suggestion_substring_case_sensitive(&pattern.to_lowercase(), &input.to_lowercase())
19}
20
21/// An implementation of [`SuggestionProvider`] that suggests a constant array of suggestions.
22pub(crate) struct FixedSuggestionProvider {
23    suggestions: &'static [&'static str],
24}
25
26impl FixedSuggestionProvider {
27    pub const fn new(suggestions: &'static [&str]) -> Self {
28        Self { suggestions }
29    }
30}
31
32impl<S, A: CommandArgumentParser<S>> SuggestionProvider<S, A> for FixedSuggestionProvider {
33    fn list_suggestions(
34        &self,
35        _context: &ArgumentSuggestionContext<'_, S, A::Value>,
36        builder: &mut SuggestionsBuilder<'_>,
37    ) {
38        let lower_prefix = builder.remaining_lowercase().to_string();
39        for suggestion in self.suggestions {
40            if matches_suggestion_substring(&lower_prefix, suggestion) {
41                builder.suggest(*suggestion);
42            }
43        }
44    }
45}