From 4d4954dc9ef5ee4e0a9e5683a2427d390b62f227 Mon Sep 17 00:00:00 2001 From: Tommaso Clini Date: Wed, 10 Jun 2026 12:37:04 +0200 Subject: [PATCH] async closures version? --- embedded-cli-macros/src/processor.rs | 10 +++++----- embedded-cli/src/cli.rs | 25 ++++++++++++++----------- embedded-cli/src/command.rs | 10 +++++----- embedded-cli/src/service.rs | 4 ++-- examples/desktop/Cargo.toml | 1 + examples/desktop/src/main.rs | 6 ++++-- 6 files changed, 31 insertions(+), 25 deletions(-) diff --git a/embedded-cli-macros/src/processor.rs b/embedded-cli-macros/src/processor.rs index 78c5e43..80a86e1 100644 --- a/embedded-cli-macros/src/processor.rs +++ b/embedded-cli-macros/src/processor.rs @@ -16,14 +16,14 @@ pub fn impl_processor(vis: &Visibility, target: &TargetType) -> Result, E: _io::Error, - F: FnMut(&mut _cli::cli::CliHandle<'_, W, E>, #ident #unnamed_lifetime) -> Result<(), E>, + F: AsyncFnMut(&mut _cli::cli::CliHandle<'_, W, E>, #ident #unnamed_lifetime) -> Result<(), E>, >( f: F, ) -> impl _cli::service::CommandProcessor { struct Processor< W: _io::Write, E: _io::Error, - F: FnMut(&mut _cli::cli::CliHandle<'_, W, E>, #ident #unnamed_lifetime) -> Result<(), E>, + F: AsyncFnMut(&mut _cli::cli::CliHandle<'_, W, E>, #ident #unnamed_lifetime) -> Result<(), E>, > { f: F, _ph: core::marker::PhantomData<(W, E)>, @@ -32,16 +32,16 @@ pub fn impl_processor(vis: &Visibility, target: &TargetType) -> Result, E: _io::Error, - F: FnMut(&mut _cli::cli::CliHandle<'_, W, E>, #ident #unnamed_lifetime) -> Result<(), E>, + F: AsyncFnMut(&mut _cli::cli::CliHandle<'_, W, E>, #ident #unnamed_lifetime) -> Result<(), E>, > _cli::service::CommandProcessor for Processor { - fn process<'a>( + async fn process<'a>( &mut self, cli: &mut _cli::cli::CliHandle<'_, W, E>, raw: _cli::command::RawCommand<'a>, ) -> Result<(), _cli::service::ProcessError<'a, E>> { let cmd = <#ident #unnamed_lifetime as _cli::service::FromRaw>::parse(raw)?; - (self.f)(cli, cmd)?; + (self.f)(cli, cmd).await?; Ok(()) } } diff --git a/embedded-cli/src/cli.rs b/embedded-cli/src/cli.rs index f2d91b7..0deb817 100644 --- a/embedded-cli/src/cli.rs +++ b/embedded-cli/src/cli.rs @@ -157,7 +157,7 @@ where /// command set and/or command processor. /// In process callback you can change some outside state /// so next calls will use different processor - pub fn process_byte>( + pub async fn process_byte>( &mut self, b: u8, processor: &mut P, @@ -165,15 +165,18 @@ where if let (Some(mut editor), Some(mut input_generator)) = (self.editor.take(), self.input_generator.take()) { - let result = input_generator - .accept(b) - .map(|input| match input { + let result = if let Some(input) = input_generator.accept(b) { + Some(match input { Input::Control(control) => { self.on_control_input::(&mut editor, control, processor) + .await } Input::Char(text) => self.on_text_input(&mut editor, text), }) - .unwrap_or(Ok(())); + } else { + None + } + .unwrap_or(Ok(())); self.editor = Some(editor); self.input_generator = Some(input_generator); @@ -244,7 +247,7 @@ where Ok(()) } - fn on_control_input>( + async fn on_control_input>( &mut self, editor: &mut Editor, control: ControlInput, @@ -259,7 +262,7 @@ where let text = editor.text_mut(); let tokens = Tokens::new(text); - self.process_input::(tokens, processor)?; + self.process_input::(tokens, processor).await?; editor.clear(); @@ -354,7 +357,7 @@ where Ok(()) } - fn process_command>( + async fn process_command>( &mut self, command: RawCommand<'_>, handler: &mut P, @@ -362,7 +365,7 @@ where let cli_writer = Writer::new(&mut self.writer); let mut handle = CliHandle::new(cli_writer); - let res = handler.process(&mut handle, command); + let res = handler.process(&mut handle, command).await; if let Some(prompt) = handle.new_prompt { self.prompt = prompt; @@ -380,7 +383,7 @@ where } #[allow(clippy::extra_unused_type_parameters)] - fn process_input>( + async fn process_input>( &mut self, tokens: Tokens<'_>, handler: &mut P, @@ -391,7 +394,7 @@ where return self.process_help::(request); } - self.process_command(command, handler)?; + self.process_command(command, handler).await?; }; Ok(()) diff --git a/embedded-cli/src/command.rs b/embedded-cli/src/command.rs index bd6cf49..e411acf 100644 --- a/embedded-cli/src/command.rs +++ b/embedded-cli/src/command.rs @@ -56,14 +56,14 @@ impl<'a> RawCommand<'a> { pub fn processor< W: Write, E: embedded_io::Error, - F: FnMut(&mut CliHandle<'_, W, E>, RawCommand<'_>) -> Result<(), E>, + F: AsyncFnMut(&mut CliHandle<'_, W, E>, RawCommand<'_>) -> Result<(), E>, >( f: F, ) -> impl CommandProcessor { struct Processor< W: Write, E: embedded_io::Error, - F: FnMut(&mut CliHandle<'_, W, E>, RawCommand<'_>) -> Result<(), E>, + F: AsyncFnMut(&mut CliHandle<'_, W, E>, RawCommand<'_>) -> Result<(), E>, > { f: F, _ph: PhantomData<(W, E)>, @@ -72,15 +72,15 @@ impl<'a> RawCommand<'a> { impl< W: Write, E: embedded_io::Error, - F: FnMut(&mut CliHandle<'_, W, E>, RawCommand<'_>) -> Result<(), E>, + F: AsyncFnMut(&mut CliHandle<'_, W, E>, RawCommand<'_>) -> Result<(), E>, > CommandProcessor for Processor { - fn process<'a>( + async fn process<'a>( &mut self, cli: &mut CliHandle<'_, W, E>, raw: RawCommand<'a>, ) -> Result<(), ProcessError<'a, E>> { - (self.f)(cli, raw)?; + (self.f)(cli, raw).await?; Ok(()) } } diff --git a/embedded-cli/src/service.rs b/embedded-cli/src/service.rs index 870e9c3..1545ab4 100644 --- a/embedded-cli/src/service.rs +++ b/embedded-cli/src/service.rs @@ -118,7 +118,7 @@ pub trait FromRaw<'a>: Sized { } pub trait CommandProcessor, E: embedded_io::Error> { - fn process<'a>( + async fn process<'a>( &mut self, cli: &mut CliHandle<'_, W, E>, raw: RawCommand<'a>, @@ -131,7 +131,7 @@ where E: embedded_io::Error, F: for<'a> FnMut(&mut CliHandle<'_, W, E>, RawCommand<'a>) -> Result<(), ProcessError<'a, E>>, { - fn process<'a>( + async fn process<'a>( &mut self, cli: &mut CliHandle<'_, W, E>, command: RawCommand<'a>, diff --git a/examples/desktop/Cargo.toml b/examples/desktop/Cargo.toml index 500d60b..82851e1 100644 --- a/examples/desktop/Cargo.toml +++ b/examples/desktop/Cargo.toml @@ -8,4 +8,5 @@ embedded-cli = { path = "../../embedded-cli" } embedded-io = "0.7.1" rand = "0.8.5" termion = "3.0.0" +tokio = { version = "1.52.3", features = ["full"] } ufmt = "0.2.0" diff --git a/examples/desktop/src/main.rs b/examples/desktop/src/main.rs index ab165e0..2517382 100644 --- a/examples/desktop/src/main.rs +++ b/examples/desktop/src/main.rs @@ -166,7 +166,8 @@ fn on_status( Ok(()) } -fn main() { +#[tokio::main] +async fn main() { let stdout = stdout().into_raw_mode().unwrap(); let writer = Writer { stdout }; @@ -238,7 +239,7 @@ Use left and right to move inside input." for byte in bytes { cli.process_byte::, _>( byte, - &mut BaseCommand::processor(|cli, command| match command { + &mut BaseCommand::processor(async |cli, command| match command { BaseCommand::Led { id, command } => on_led(cli, &mut state, id, command), BaseCommand::Adc { id, command } => on_adc(cli, &mut state, id, command), BaseCommand::Status => on_status(cli, &mut state), @@ -248,6 +249,7 @@ Use left and right to move inside input." } }), ) + .await .unwrap(); }