ushell 0.3.1

Embedded shell over serial connection
Documentation
use core::str::FromStr;

use crate::heapless::String;
use crate::uluru::LRUCache;

pub trait History<const COMMAND_LEN: usize> {
    fn reset(&mut self);
    fn push(&mut self, command: &str) -> Result<(), ()>;
    fn go_back(&mut self) -> Option<String<COMMAND_LEN>>;
    fn go_forward(&mut self) -> Option<String<COMMAND_LEN>>;
}

pub struct NoHistory;

impl<const COMMAND_LEN: usize> History<COMMAND_LEN> for NoHistory {
    fn reset(&mut self) {}

    fn push(&mut self, _command: &str) -> Result<(), ()> {
        Ok(())
    }

    fn go_back(&mut self) -> Option<String<COMMAND_LEN>> {
        None
    }

    fn go_forward(&mut self) -> Option<String<COMMAND_LEN>> {
        None
    }
}

#[derive(Default)]
pub struct LRUHistory<const COMMAND_LEN: usize, const HISTORY_LEN: usize> {
    history: LRUCache<String<COMMAND_LEN>, HISTORY_LEN>,
    cursor: usize,
}

impl<const COMMAND_LEN: usize, const HISTORY_LEN: usize> History<COMMAND_LEN>
    for LRUHistory<COMMAND_LEN, HISTORY_LEN>
{
    fn reset(&mut self) {
        self.cursor = 0;
        self.history = LRUCache::default();
    }

    fn push(&mut self, command: &str) -> Result<(), ()> {
        if command.len() > 0 && HISTORY_LEN > 0 {
            if self.history.find(|item| item.as_str() == command).is_none() {
                let history_entry = String::from_str(command)?;
                self.history.insert(history_entry);
            }
        }
        self.cursor = 0;
        Ok(())
    }

    fn go_back(&mut self) -> Option<String<COMMAND_LEN>> {
        if self.history.len() == 0 || self.cursor == self.history.len() {
            None
        } else {
            let cursor = self.cursor;
            self.cursor += 1;
            self.history.get(cursor).cloned()
        }
    }

    fn go_forward(&mut self) -> Option<String<COMMAND_LEN>> {
        if self.cursor == 0 || self.history.len() == 0 {
            None
        } else {
            self.cursor -= 1;
            let cursor = self.cursor;
            self.history.get(cursor).cloned()
        }
    }
}