funbiscuit / embedded-cli-rs

CLI in Rust with autocompletion, subcommands, options, help and history for embedded systems (like Arduino or STM32)
Apache License 2.0
79 stars 4 forks source link

Add support for wrapping of generated string slices #3

Open funbiscuit opened 9 months ago

funbiscuit commented 9 months ago

About

Currently macro generates implementation of Autocomplete and Help traits by using normal string slices. On some platforms (AVR) it makes sense to use different memory to store such data and make more RAM for other things (not use static RAM for literals). In Rust this can be done by using avr-progmem crate. This crate allows to wrap normal string literal with macro avr_progmem::progmem_str and then instead of RAM, progmem will be used. In arduino example it is already used for example strings.

Proposed implementation

Add extra optional attribute wrap_str to Command macro. This attribute should take template that will be used to render all string slices that macro generates. For example:

use avr_progmem::progmem_str as F;

#[derive(Command)]
#[command(wrap_str = "F!({})"):
enum Base {
    /// Stop CLI and exit
    Exit,
}

When code expanded it will contain following:

writer.writeln_str(F!("Stop CLI and exit"))?;

So {} is acted as placeholder for original string. Which means that by default wrap_str is equal to {}. Without extra wrapping same code would look like this:

writer.writeln_str("Stop CLI and exit")?;

Attribute should be placeable on both enum and variant so we can enable wrapping for some variants while other variants will use normal RAM:

#[derive(Command)]
enum Base {
    /// Just command
    Command,

    /// This is a command with some very long text that should not take static RAM
    #[command(wrap_str = "F!({})"):
    Exit,
}

In this case only exit command strings will be wrapped with macro.

After implementation, arduino example should be updated to minimize static RAM usage.