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}