ushell/
autocomplete.rs

1use core::str::FromStr;
2
3use crate::heapless::String;
4
5pub trait Autocomplete<const CMD_LEN: usize> {
6    fn suggest(&self, prefix: &str) -> Option<String<CMD_LEN>>;
7}
8
9pub struct NoAutocomplete;
10
11impl<const CMD_LEN: usize> Autocomplete<CMD_LEN> for NoAutocomplete {
12    fn suggest(&self, _prefix: &str) -> Option<String<CMD_LEN>> {
13        None
14    }
15}
16
17pub struct FnAutocomplete<const CMD_LEN: usize>(fn(&str) -> Option<String<CMD_LEN>>);
18
19impl<const CMD_LEN: usize> Autocomplete<CMD_LEN> for FnAutocomplete<CMD_LEN> {
20    fn suggest(&self, prefix: &str) -> Option<String<CMD_LEN>> {
21        self.0(prefix)
22    }
23}
24
25pub struct StaticAutocomplete<const N: usize>(pub [&'static str; N]);
26
27impl<const CMD_LEN: usize, const N: usize> Autocomplete<CMD_LEN> for StaticAutocomplete<N> {
28    fn suggest(&self, prefix: &str) -> Option<String<CMD_LEN>> {
29        if prefix.is_empty() {
30            return None;
31        }
32        for item in self.0.iter() {
33            if item.starts_with(prefix) {
34                let (_, suffix) = item.split_at(prefix.len());
35                return String::from_str(suffix).ok();
36            }
37        }
38        None
39    }
40}