From ef10eec21674870856edd35d6cbf283969800d49 Mon Sep 17 00:00:00 2001 From: rhetenor Date: Sat, 29 Aug 2026 20:19:14 +0000 Subject: [PATCH] implement error view which displays all error on the display --- Cargo.lock | 18 +++++ Cargo.toml | 1 + src/navigation/navigation.rs | 42 ++++++++++-- src/peripherals/storage.rs | 12 ++-- src/peripherals/storage/cardstore.rs | 18 ++++- src/peripherals/storage/flash_store.rs | 37 ++++++++-- src/views.rs | 1 + src/views/card_view.rs | 5 +- src/views/error_view.rs | 94 ++++++++++++++++++++++++++ src/views/flash_info_view.rs | 23 +++++-- src/views/journal_view.rs | 5 +- src/views/main_menu.rs | 23 ++++--- src/views/menu_item.rs | 2 + src/views/scan_menu.rs | 91 +++++++++++++------------ src/views/settings_menu.rs | 21 +++--- src/views/status_bar.rs | 2 + src/views/view.rs | 13 ++-- 17 files changed, 316 insertions(+), 92 deletions(-) create mode 100644 src/views/error_view.rs diff --git a/Cargo.lock b/Cargo.lock index b278b60..f915330 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -363,6 +363,7 @@ dependencies = [ "embedded-hal-bus", "embedded-io 0.7.1", "embedded-storage", + "embedded-text", "esp-alloc", "esp-bootloader-esp-idf", "esp-hal", @@ -1049,6 +1050,17 @@ dependencies = [ "embedded-storage", ] +[[package]] +name = "embedded-text" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cf5c72c52db2f7dbe4a9c1ed81cd21301e8d66311b194fa41c04fb4f71843ba" +dependencies = [ + "az", + "embedded-graphics", + "object-chain", +] + [[package]] name = "enumset" version = "1.1.14" @@ -2130,6 +2142,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "object-chain" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41af26158b0f5530f7b79955006c2727cd23d0d8e7c3109dc316db0a919784dd" + [[package]] name = "once_cell" version = "1.21.4" diff --git a/Cargo.toml b/Cargo.toml index 7ac5eb3..2e4a06e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,7 @@ esp-storage = "0.9.0" embedded-storage = "0.3.1" binary_serde = "1.0.25" static_assertions = { version = "1.1.0", default-features = false } +embedded-text = "0.7.3" [build-dependencies] log = "0.4.27" diff --git a/src/navigation/navigation.rs b/src/navigation/navigation.rs index b59b5dc..d47dc78 100644 --- a/src/navigation/navigation.rs +++ b/src/navigation/navigation.rs @@ -1,10 +1,15 @@ +use crate::alloc::string::ToString; use crate::card::model::Card; use crate::navigation::inputs::ButtonAction; use crate::navigation::inputs::Inputs; use crate::navigation::outputs::Outputs; use crate::navigation::state::NavigationState; use crate::peripherals::Peripherals; +use crate::views::error_view::ErrorView; use crate::views::view::View; +use alloc::boxed::Box; +use alloc::string::String; +use core::error; use embassy_futures::select::{Either, select}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; @@ -32,21 +37,45 @@ pub trait Navigable { &self, outputs: &mut Outputs, peripherals: &Peripherals, - ) -> impl core::future::Future + Send; + ) -> impl core::future::Future>> + Send; fn handle_input(&self, input: Action) -> impl core::future::Future + Send; } #[embassy_executor::task] pub async fn run(mut inputs: Inputs, mut outputs: Outputs, peripherals: &'static Peripherals) { + async fn display_error( + error: String, + state: &mut NavigationState, + outputs: &mut Outputs, + peripherals: &Peripherals, + ) -> () { + let error_view = ErrorView { + error: error.to_string(), + }; + state.screens.push(View::Error(error_view)); + state + .screens + .last() + // Unwrap: we just pushed the state + .unwrap() + .display(outputs, peripherals) + .await + // Unwrap: display will panic on error in error view + .unwrap(); + } + log::info!("starting navigation"); let mut state = NavigationState::new(); - state + if let Err(error) = state .screens .last() .unwrap() .display(&mut outputs, peripherals) - .await; + .await + { + display_error(error.to_string(), &mut state, &mut outputs, &peripherals).await; + }; loop { let selection = select( @@ -92,12 +121,15 @@ pub async fn run(mut inputs: Inputs, mut outputs: Outputs, peripherals: &'static state.screens.push(new_state.view); if action != Action::Timer || new_state.redraw { - state + if let Err(error) = state .screens .last() .unwrap() .display(&mut outputs, peripherals) - .await; + .await + { + display_error(error.to_string(), &mut state, &mut outputs, &peripherals).await; + } } Timer::after(Duration::from_millis(DEBOUNCE_DURATION_MILLIS)).await; diff --git a/src/peripherals/storage.rs b/src/peripherals/storage.rs index 5a2344e..9e4b528 100644 --- a/src/peripherals/storage.rs +++ b/src/peripherals/storage.rs @@ -1,6 +1,6 @@ pub struct MemoryRegion { - offset: u32, - size: usize, + pub offset: u32, + pub size: usize, } impl MemoryRegion { @@ -15,13 +15,13 @@ impl MemoryRegion { } } -const MAX_FLASH: usize = 16 * 1024 * 1024; +pub const MAX_FLASH: usize = 16 * 1024 * 1024; -const MAGIC_REGION: MemoryRegion = MemoryRegion::new(0, 4); +pub const MAGIC_REGION: MemoryRegion = MemoryRegion::new(0, 4); -const SETTINGS_REGION: MemoryRegion = MemoryRegion::new(MAGIC_REGION.end() as u32, 1024); +pub const SETTINGS_REGION: MemoryRegion = MemoryRegion::new(MAGIC_REGION.end() as u32, 1024); -const CARDSTORE_REGION: MemoryRegion = MemoryRegion::new( +pub const CARDSTORE_REGION: MemoryRegion = MemoryRegion::new( SETTINGS_REGION.end() as u32, MAX_FLASH - SETTINGS_REGION.end(), ); diff --git a/src/peripherals/storage/cardstore.rs b/src/peripherals/storage/cardstore.rs index 9473c64..4d9f2e3 100644 --- a/src/peripherals/storage/cardstore.rs +++ b/src/peripherals/storage/cardstore.rs @@ -1,5 +1,7 @@ use alloc::collections::BTreeMap; use alloc::vec::Vec; +use core::error::Error; +use core::fmt::Display; use binary_serde::{BinarySerde, DeserializeError, Endianness}; @@ -67,7 +69,19 @@ impl AllocationTableEntry { pub enum CardStoreError { Store(FlashStoreError), CorruptedEntry(DeserializeError), - NoEntry, + NoEntry(u32), +} + +impl Error for CardStoreError {} + +impl Display for CardStoreError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + CardStoreError::Store(e) => e.fmt(f), + CardStoreError::CorruptedEntry(e) => e.fmt(f), + CardStoreError::NoEntry(uuid) => write!(f, "No Card Entry\nuuid: 0x{uuid:x}"), + } + } } impl From for CardStoreError { @@ -129,7 +143,7 @@ impl CardStore { let entry = self .allocation_table .get(&uuid) - .ok_or(CardStoreError::NoEntry)?; + .ok_or(CardStoreError::NoEntry(uuid))?; let mut raw_card: [u8; size_of::()] = [0; size_of::()]; self.store.read(entry.offset, &mut raw_card).await?; diff --git a/src/peripherals/storage/flash_store.rs b/src/peripherals/storage/flash_store.rs index e48a139..76f45a1 100644 --- a/src/peripherals/storage/flash_store.rs +++ b/src/peripherals/storage/flash_store.rs @@ -1,3 +1,6 @@ +use core::error::Error; +use core::fmt::Display; + use crate::navigation::navigation::Mutex; use embedded_storage::nor_flash::NorFlash; use embedded_storage::nor_flash::ReadNorFlash; @@ -5,7 +8,23 @@ use esp_storage::{FlashStorage, FlashStorageError}; use crate::peripherals::storage::MAGIC_REGION; -pub type FlashStoreError = FlashStorageError; +#[derive(Debug)] +pub struct FlashStoreError(FlashStorageError); + +impl From for FlashStoreError { + fn from(value: FlashStorageError) -> Self { + Self(value) + } +} + +impl Error for FlashStoreError {} + +impl Display for FlashStoreError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + use core::fmt::Debug; + self.0.fmt(f) + } +} const FLASH_ADDR: u32 = 0x9000; @@ -37,12 +56,17 @@ impl FlashStore { } pub async fn read(&self, offset: u32, bytes: &mut [u8]) -> Result<(), FlashStoreError> { - self.storage.lock().await.read(FLASH_ADDR + offset, bytes) + self.storage.lock().await.read(FLASH_ADDR + offset, bytes)?; + Ok(()) } pub async fn write(&self, offset: u32, bytes: &mut [u8]) -> Result<(), FlashStoreError> { log::debug!("Writing {} bytes at offset 0x{offset:08x}", bytes.len()); - self.storage.lock().await.write(FLASH_ADDR + offset, bytes) + self.storage + .lock() + .await + .write(FLASH_ADDR + offset, bytes)?; + Ok(()) } pub async fn write_erase(&self, offset: u32, bytes: &mut [u8]) -> Result<(), FlashStoreError> { @@ -52,7 +76,8 @@ impl FlashStore { ); let mut lock = self.storage.lock().await; lock.erase(FLASH_ADDR + offset, FLASH_ADDR + bytes.len() as u32)?; - lock.write(FLASH_ADDR + offset, bytes) + lock.write(FLASH_ADDR + offset, bytes)?; + Ok(()) } pub fn has_magic_bytes(storage: &mut FlashStorage) -> Result { @@ -75,7 +100,9 @@ impl FlashStore { if Self::has_magic_bytes(storage)? { Ok(()) } else { - Err(FlashStoreError::Other(FLASH_INITIALIZE_MAGIC as i32)) + Err(FlashStoreError(FlashStorageError::Other( + FLASH_INITIALIZE_MAGIC as i32, + ))) } } } diff --git a/src/views.rs b/src/views.rs index 08094c2..baa453a 100644 --- a/src/views.rs +++ b/src/views.rs @@ -1,4 +1,5 @@ pub mod card_view; +pub mod error_view; pub mod flash_info_view; pub mod journal_view; pub mod main_menu; diff --git a/src/views/card_view.rs b/src/views/card_view.rs index 5d173f3..65651b6 100644 --- a/src/views/card_view.rs +++ b/src/views/card_view.rs @@ -2,7 +2,9 @@ use crate::display::sprite::render_sprite_onto_ili9341; use crate::navigation::navigation::NewState; use crate::navigation::outputs::Outputs; use crate::peripherals::Peripherals; +use alloc::boxed::Box; use alloc::format; +use core::error; use embedded_graphics::mono_font::MonoTextStyle; use embedded_graphics::mono_font::ascii::FONT_6X10; use embedded_graphics::pixelcolor::Rgb565; @@ -30,7 +32,7 @@ impl Navigable for CardView { &self, outputs: &mut Outputs, _: &Peripherals, - ) -> impl core::future::Future + Send { + ) -> impl core::future::Future>> + Send { async move { let display = &mut outputs.primary_display; display.clear(Rgb565::BLACK).unwrap(); @@ -100,6 +102,7 @@ impl Navigable for CardView { let palette: Palette = self.card.cardtype.clone().into(); render_sprite_onto_ili9341(display, self.card.sprite.data.as_slice(), &palette); + Ok(()) } } diff --git a/src/views/error_view.rs b/src/views/error_view.rs new file mode 100644 index 0000000..999e090 --- /dev/null +++ b/src/views/error_view.rs @@ -0,0 +1,94 @@ +use crate::navigation::navigation::Action; +use crate::navigation::navigation::Navigable; +use crate::navigation::navigation::NewState; +use crate::navigation::outputs::Outputs; +use crate::peripherals::Peripherals; +use crate::views::view::View; +use alloc::boxed::Box; +use alloc::format; +use alloc::string::String; +use core::error; +use embedded_graphics::{ + Drawable, + mono_font::{MonoTextStyle, ascii::FONT_10X20}, + pixelcolor::Rgb565, + prelude::*, + primitives::Rectangle, + text::Text, +}; + +use embedded_text::{ + TextBox, + alignment::HorizontalAlignment, + style::{HeightMode, TextBoxStyleBuilder}, +}; +#[derive(Debug, Clone)] +pub struct ErrorView { + pub error: String, +} + +impl Navigable for ErrorView { + fn display( + &self, + outputs: &mut Outputs, + _: &Peripherals, + ) -> impl core::future::Future>> + Send { + async move { + let style = MonoTextStyle::new(&FONT_10X20, Rgb565::RED); + let display_area = outputs.primary_display.bounding_box(); + Text::new( + "Error", + Point::new((display_area.size.width / 2 - 25) as i32, 30), + style, + ) + .draw(&mut outputs.primary_display) + .unwrap_or_else(|error| { + panic!( + "Error: {error:?}\nDraw error while rendering error: {}", + self.error + ) + }); + + let style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE); + let textbox_style = TextBoxStyleBuilder::new() + .height_mode(HeightMode::FitToText) + .alignment(HorizontalAlignment::Center) + .build(); + + let bounds = Rectangle::new(Point::new(0, 30), display_area.size); + + TextBox::with_textbox_style(&format!("{}", self.error), bounds, style, textbox_style) + .draw(&mut outputs.primary_display) + .unwrap_or_else(|error| { + panic!( + "Error: {error:?}\nDraw error while rendering error: {}", + self.error + ) + }); + Ok(()) + } + } + + fn handle_input(&self, input: Action) -> impl core::future::Future + Send { + async move { + let Action::Button(input) = input else { + // Skip timer inputs + return NewState { + view: View::Error(self.clone()), + replace_view: true, + redraw: false, + }; + }; + + let new_menu = match input { + _ => View::Error(self.clone()), + }; + + NewState { + replace_view: matches!(new_menu, View::FlashInfo(_)), + view: new_menu, + redraw: true, + } + } + } +} diff --git a/src/views/flash_info_view.rs b/src/views/flash_info_view.rs index 84bb414..2299eb5 100644 --- a/src/views/flash_info_view.rs +++ b/src/views/flash_info_view.rs @@ -1,10 +1,12 @@ -use crate::navigation::inputs::ButtonAction; use crate::navigation::navigation::Action; use crate::navigation::navigation::Navigable; use crate::navigation::navigation::NewState; use crate::navigation::outputs::Outputs; use crate::peripherals::Peripherals; +use crate::peripherals::storage::MAGIC_REGION; use crate::views::view::View; +use alloc::boxed::Box; +use core::error; use embedded_graphics::mono_font::MonoTextStyle; use embedded_graphics::mono_font::ascii::FONT_10X20; use embedded_graphics::pixelcolor::Rgb565; @@ -22,11 +24,20 @@ impl Navigable for FlashInfoView { &self, outputs: &mut Outputs, peripherals: &Peripherals, - ) -> impl core::future::Future + Send { - let style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE); - Text::new("Flash Initialized: {:?}", Point::new(40, 40), style); - - core::future::ready(()) + ) -> impl core::future::Future>> + Send { + async move { + let style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE); + let mut magic_bytes: [u8; MAGIC_REGION.size] = [0; MAGIC_REGION.size]; + peripherals + .store + .lock() + .await + .flash_store + .read(MAGIC_REGION.offset, &mut magic_bytes) + .await?; + Text::new("Flash Initialized: {:?}", Point::new(40, 40), style); + Ok(()) + } } fn handle_input(&self, input: Action) -> impl core::future::Future + Send { diff --git a/src/views/journal_view.rs b/src/views/journal_view.rs index 5f49292..61b6fcb 100644 --- a/src/views/journal_view.rs +++ b/src/views/journal_view.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; +use core::error; use crate::peripherals::Peripherals; use core::future; @@ -27,9 +29,10 @@ impl Navigable for JournalView { &self, outputs: &mut Outputs, _: &Peripherals, - ) -> impl core::future::Future + Send { + ) -> impl core::future::Future>> + Send { async move { outputs.primary_display.clear(Rgb565::BLACK).unwrap(); + Ok(()) } } diff --git a/src/views/main_menu.rs b/src/views/main_menu.rs index 5149c0d..2c50eb6 100644 --- a/src/views/main_menu.rs +++ b/src/views/main_menu.rs @@ -1,5 +1,7 @@ use crate::peripherals::Peripherals; +use alloc::boxed::Box; use alloc::vec; +use core::error; use crate::card::model::Card; use crate::card::{decoder::split_nfc_hex, mock::*}; @@ -15,6 +17,7 @@ use embedded_graphics::pixelcolor::Rgb565; use embedded_graphics::prelude::RgbColor; use embedded_graphics_core::draw_target::DrawTarget; +use crate::peripherals::storage::cardstore::CardStoreError; pub const MAX_SELECTED: i32 = 4; #[derive(Debug, Clone)] @@ -26,17 +29,19 @@ impl Navigable for MainMenu { fn display( &self, outputs: &mut Outputs, - _: &Peripherals - ) -> impl core::future::Future + Send { - let display = &mut outputs.primary_display; - display.clear(Rgb565::BLACK).unwrap(); + _: &Peripherals, + ) -> impl core::future::Future>> + Send { + async move { + let display = &mut outputs.primary_display; + display.clear(Rgb565::BLACK).unwrap(); - menu_item::show(display, "Scan card", 0, self.selected); - menu_item::show(display, "Last card", 1, self.selected); - menu_item::show(display, "Journal", 2, self.selected); - menu_item::show(display, "Settings", 3, self.selected); + menu_item::show(display, "Scan card", 0, self.selected); + menu_item::show(display, "Last card", 1, self.selected); + menu_item::show(display, "Journal", 2, self.selected); + menu_item::show(display, "Settings", 3, self.selected); - core::future::ready(()) + Ok(()) + } } fn handle_input(&self, input: Action) -> impl core::future::Future + Send { diff --git a/src/views/menu_item.rs b/src/views/menu_item.rs index 5647c11..3a040f0 100644 --- a/src/views/menu_item.rs +++ b/src/views/menu_item.rs @@ -1,3 +1,5 @@ +use alloc::boxed::Box; +use core::error; use crate::peripherals::Peripherals; use embedded_graphics::Drawable; use embedded_graphics::draw_target::DrawTarget; diff --git a/src/views/scan_menu.rs b/src/views/scan_menu.rs index 874999e..1fe434f 100644 --- a/src/views/scan_menu.rs +++ b/src/views/scan_menu.rs @@ -3,6 +3,8 @@ use crate::navigation::navigation::CARD_DATA; use crate::navigation::navigation::NewState; use crate::navigation::outputs::Outputs; use crate::peripherals::Peripherals; +use alloc::boxed::Box; +use core::error; use alloc::format; use embedded_graphics::Drawable; @@ -37,55 +39,56 @@ impl Navigable for ScanMenu { fn display( &self, outputs: &mut Outputs, - _: &Peripherals - ) -> impl core::future::Future + Send { - let display = &mut outputs.primary_display; - let style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE); - display.clear(Rgb565::BLACK).unwrap(); + _: &Peripherals, + ) -> impl core::future::Future>> + Send { + async move { + let display = &mut outputs.primary_display; + let style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE); + display.clear(Rgb565::BLACK).unwrap(); - let display_area = display.bounding_box(); + let display_area = display.bounding_box(); - Text::new("Scanning...", Point::new(20, 30), style) + Text::new("Scanning...", Point::new(20, 30), style) + .draw(display) + .unwrap(); + + // Create styles used by the drawing operations. + let arc_stroke = PrimitiveStyleBuilder::new() + .stroke_color(Rgb565::WHITE) + .stroke_width(5) + .stroke_alignment(StrokeAlignment::Inside) + .build(); + let character_style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE); + let text_style = TextStyleBuilder::new() + .baseline(Baseline::Middle) + .alignment(Alignment::Center) + .build(); + + let sweep = self.progress as f32 * 360.0 / 255.0; + + let width = display_area.size.width; + let bounding_box = + Rectangle::with_center(display_area.center(), Size::new_equal(4 * width / 5)); + // log::info!("bounding_box: {:?}", bounding_box); + // log::info!("display_area: {:?}", display_area); + // Draw an arc with a 5px wide stroke. + Arc::new( + bounding_box.top_left, + bounding_box.size.width, + 90.0.deg(), + sweep.deg(), + ) + .into_styled(arc_stroke) .draw(display) .unwrap(); - // Create styles used by the drawing operations. - let arc_stroke = PrimitiveStyleBuilder::new() - .stroke_color(Rgb565::WHITE) - .stroke_width(5) - .stroke_alignment(StrokeAlignment::Inside) - .build(); - let character_style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE); - let text_style = TextStyleBuilder::new() - .baseline(Baseline::Middle) - .alignment(Alignment::Center) - .build(); - - let sweep = self.progress as f32 * 360.0 / 255.0; - - let width = display_area.size.width; - let bounding_box = - Rectangle::with_center(display_area.center(), Size::new_equal(4 * width / 5)); - // log::info!("bounding_box: {:?}", bounding_box); - // log::info!("display_area: {:?}", display_area); - // Draw an arc with a 5px wide stroke. - Arc::new( - bounding_box.top_left, - bounding_box.size.width, - 90.0.deg(), - sweep.deg(), - ) - .into_styled(arc_stroke) - .draw(display) - .unwrap(); - - // Draw centered text. - let text = format!("{:.2}%", 100. * (self.progress as f32) / 255.); - Text::with_text_style(&text, display_area.center(), character_style, text_style) - .draw(display) - .unwrap(); - - core::future::ready(()) + // Draw centered text. + let text = format!("{:.2}%", 100. * (self.progress as f32) / 255.); + Text::with_text_style(&text, display_area.center(), character_style, text_style) + .draw(display) + .unwrap(); + Ok(()) + } } fn handle_input(&self, input: Action) -> impl core::future::Future + Send { diff --git a/src/views/settings_menu.rs b/src/views/settings_menu.rs index 410b21e..9bcf327 100644 --- a/src/views/settings_menu.rs +++ b/src/views/settings_menu.rs @@ -2,6 +2,8 @@ use crate::navigation::navigation::{Action, Navigable, NewState}; use crate::navigation::outputs::Outputs; use crate::peripherals::Peripherals; use crate::views::{flash_info_view::FlashInfoView, menu_item, view::View}; +use alloc::boxed::Box; +use core::error; use crate::navigation::inputs::ButtonAction; @@ -20,15 +22,16 @@ impl Navigable for SettingsMenu { fn display( &self, outputs: &mut Outputs, - _: &Peripherals - ) -> impl core::future::Future + Send { - let display = &mut outputs.primary_display; - display.clear(Rgb565::BLACK).unwrap(); - menu_item::show(display, "System Inforation", 0, self.selected); - menu_item::show(display, "Wifi Information", 1, self.selected); - menu_item::show(display, "Flash Information", 2, self.selected); - - core::future::ready(()) + _: &Peripherals, + ) -> impl core::future::Future>> + Send { + async move { + let display = &mut outputs.primary_display; + display.clear(Rgb565::BLACK).unwrap(); + menu_item::show(display, "System Inforation", 0, self.selected); + menu_item::show(display, "Wifi Information", 1, self.selected); + menu_item::show(display, "Flash Information", 2, self.selected); + Ok(()) + } } fn handle_input(&self, input: Action) -> impl core::future::Future + Send { diff --git a/src/views/status_bar.rs b/src/views/status_bar.rs index 0233e40..c274545 100644 --- a/src/views/status_bar.rs +++ b/src/views/status_bar.rs @@ -1 +1,3 @@ +use alloc::boxed::Box; +use core::error; // Status bar view module diff --git a/src/views/view.rs b/src/views/view.rs index 4a62168..2d18f84 100644 --- a/src/views/view.rs +++ b/src/views/view.rs @@ -2,14 +2,17 @@ use crate::navigation::outputs::Outputs; use crate::peripherals::Peripherals; use crate::views::card_view::CardView; use crate::views::{ - flash_info_view::FlashInfoView, journal_view::JournalView, main_menu::MainMenu, - scan_menu::ScanMenu, settings_menu::SettingsMenu, + error_view::ErrorView, flash_info_view::FlashInfoView, journal_view::JournalView, + main_menu::MainMenu, scan_menu::ScanMenu, settings_menu::SettingsMenu, }; +use alloc::boxed::Box; +use core::error; use crate::navigation::navigation::{Navigable, NewState}; #[derive(Debug, Clone)] pub enum View { + Error(ErrorView), Main(MainMenu), Scan(ScanMenu), Settings(SettingsMenu), @@ -22,10 +25,11 @@ impl Navigable for View { fn display( &self, outputs: &mut Outputs, - peripherals: &Peripherals - ) -> impl core::future::Future + Send { + peripherals: &Peripherals, + ) -> impl core::future::Future>> + Send { async move { match self { + View::Error(error_view) => error_view.display(outputs, peripherals).await, View::Main(main_menu) => main_menu.display(outputs, peripherals).await, View::Scan(scan_menu) => scan_menu.display(outputs, peripherals).await, View::Settings(settings_menu) => settings_menu.display(outputs, peripherals).await, @@ -44,6 +48,7 @@ impl Navigable for View { ) -> impl core::future::Future + Send { async move { match self { + View::Error(error_view) => error_view.handle_input(input).await, View::Main(main_menu) => main_menu.handle_input(input).await, View::Scan(scan_menu) => scan_menu.handle_input(input).await, View::Settings(settings_menu) => settings_menu.handle_input(input).await, -- 2.39.5