diff --git a/core/embed/rust/src/lib.rs b/core/embed/rust/src/lib.rs index 3727d38d3..3e7b36bf7 100644 --- a/core/embed/rust/src/lib.rs +++ b/core/embed/rust/src/lib.rs @@ -51,9 +51,7 @@ fn panic_debug(panic_info: &core::panic::PanicInfo) -> ! { if let Some(location) = panic_info.location() { let file = location.file(); - print!(file); - print!(":"); - println!(inttostr!(location.line())); + println!("Panic at {}:{}:{}", file, location.line(), location.column()); trezorhal::fatal_error::__fatal_error("", "rs", file, location.line(), ""); } else { trezorhal::fatal_error::__fatal_error("", "rs", "", 0, ""); diff --git a/core/embed/rust/src/micropython/buffer.rs b/core/embed/rust/src/micropython/buffer.rs index ee9247111..82da9ae6e 100644 --- a/core/embed/rust/src/micropython/buffer.rs +++ b/core/embed/rust/src/micropython/buffer.rs @@ -20,7 +20,7 @@ use super::ffi; /// The `off` field represents offset from the `ptr` and allows us to do /// substring slices while keeping the head pointer as required by GC. #[repr(C)] -#[derive(Debug, Copy, Clone)] +#[derive(Copy, Clone)] pub struct StrBuffer { ptr: *const u8, len: u16, @@ -165,6 +165,18 @@ impl From<&'static str> for StrBuffer { } } +#[cfg(feature="debug")] +impl ufmt::uDebug for StrBuffer { + fn fmt(&self, f: &mut ufmt::Formatter<'_, W>) -> Result<(), W::Error> + where + W: ufmt::uWrite + ?Sized { + f.write_str("StrBuffer(")?; + f.write_str(self.as_ref())?; + f.write_str(")")?; + Ok(()) + } +} + fn get_buffer_info(obj: Obj, flags: u32) -> Result { let mut bufinfo = ffi::mp_buffer_info_t { buf: ptr::null_mut(), diff --git a/core/embed/rust/src/micropython/macros.rs b/core/embed/rust/src/micropython/macros.rs index daab06d6f..db2ace98a 100644 --- a/core/embed/rust/src/micropython/macros.rs +++ b/core/embed/rust/src/micropython/macros.rs @@ -261,15 +261,35 @@ macro_rules! attr_tuple { }); } +// from https://docs.rs/ufmt/latest/ufmt/ +// like `std::format!` it returns a `std::String` but uses `uwrite!` instead of +// `write!` +macro_rules! uformat { + // IMPORTANT use `tt` fragments instead of `expr` fragments (i.e. `$($exprs:expr),*`) + ($len:expr, $($tt:tt)*) => {{ + let mut s = heapless::String::<$len>::new(); + match ufmt::uwrite!(&mut s, $($tt)*) { + Ok(_) => Ok(s), + Err(e) => Err(e), + } + }}; +} + /// Print arbitrary amounts of slices into a terminal. /// Does not include a newline at the end. /// Does not do anything when not in debugging mode. #[allow(unused_macros)] // Should be used only for debugging purposes macro_rules! print { - ($($string:expr),+) => { + ($($tt:tt)*) => { #[cfg(feature = "debug")] { - $(crate::micropython::print::print($string);)+ + match uformat!(256, $($tt)*) { + Ok(u) => crate::micropython::print::print(&u), + Err(e) => { + crate::micropython::print::print("Error: "); + crate::micropython::print::print(&unwrap!(uformat!(256, "{:?}", e))); + } + }; } } } @@ -279,8 +299,9 @@ macro_rules! print { /// Does not do anything when not in debugging mode. #[allow(unused_macros)] // Should be used only for debugging purposes macro_rules! println { - ($($string:expr),+) => { + ($($tt:tt)*) => { // Just delegating to print! and adding a newline - print!($($string),+, "\n"); + print!($($tt)*); + print!("\n"); } } diff --git a/core/embed/rust/src/strutil.rs b/core/embed/rust/src/strutil.rs index 3210ddc4a..3fc4d0893 100644 --- a/core/embed/rust/src/strutil.rs +++ b/core/embed/rust/src/strutil.rs @@ -195,3 +195,32 @@ impl<'a, 'b> PartialEq> for TString<'b> { } impl Eq for TString<'_> {} + + +#[cfg(feature="debug")] +impl ufmt::uDebug for TString<'_> { + fn fmt(&self, f: &mut ufmt::Formatter<'_, W>) -> Result<(), W::Error> + where + W: ufmt::uWrite + ?Sized { + match self { + TString::Allocated(buf) => { + f.write_str("Allocated(")?; + buf.fmt(f)?; + f.write_str(")")?; + } + TString::Translation { tr, offset } => { + f.write_str("Translation(")?; + tr.fmt(f)?; + f.write_str(", ")?; + offset.fmt(f)?; + f.write_str(")")?; + } + TString::Str(s) => { + f.write_str("Str(")?; + f.write_str(s)?; + f.write_str(")")?; + } + } + Ok(()) + } +} diff --git a/core/embed/rust/src/translations/generated/translated_string.rs b/core/embed/rust/src/translations/generated/translated_string.rs index 337b403c7..360306799 100644 --- a/core/embed/rust/src/translations/generated/translated_string.rs +++ b/core/embed/rust/src/translations/generated/translated_string.rs @@ -6,7 +6,8 @@ #[cfg(feature = "micropython")] use crate::micropython::qstr::Qstr; -#[derive(Debug, Copy, Clone, FromPrimitive, PartialEq, Eq)] +#[derive(Copy, Clone, FromPrimitive, PartialEq, Eq)] +#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] #[repr(u16)] #[allow(non_camel_case_types)] pub enum TranslatedString { diff --git a/core/embed/rust/src/translations/generated/translated_string.rs.mako b/core/embed/rust/src/translations/generated/translated_string.rs.mako index 74acf6757..314772469 100644 --- a/core/embed/rust/src/translations/generated/translated_string.rs.mako +++ b/core/embed/rust/src/translations/generated/translated_string.rs.mako @@ -35,7 +35,8 @@ en_data = json.loads(en_file.read_text())["translations"] #[cfg(feature = "micropython")] use crate::micropython::qstr::Qstr; -#[derive(Debug, Copy, Clone, FromPrimitive, PartialEq, Eq)] +#[derive(Copy, Clone, FromPrimitive, PartialEq, Eq)] +#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] #[repr(u16)] #[allow(non_camel_case_types)] pub enum TranslatedString { diff --git a/core/embed/rust/src/ui/component/base.rs b/core/embed/rust/src/ui/component/base.rs index 6703440b7..371e951b2 100644 --- a/core/embed/rust/src/ui/component/base.rs +++ b/core/embed/rust/src/ui/component/base.rs @@ -416,6 +416,7 @@ where } #[derive(Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] pub enum Event { #[cfg(feature = "button")] Button(ButtonEvent), @@ -436,6 +437,7 @@ pub enum Event { } #[derive(Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] pub struct TimerToken(u32); impl TimerToken { diff --git a/core/embed/rust/src/ui/event.rs b/core/embed/rust/src/ui/event.rs index fd1f55554..dcbcc8253 100644 --- a/core/embed/rust/src/ui/event.rs +++ b/core/embed/rust/src/ui/event.rs @@ -2,12 +2,14 @@ use crate::{error, ui::geometry::Point}; use core::convert::TryInto; #[derive(Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] pub enum PhysicalButton { Left, Right, } #[derive(Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] pub enum ButtonEvent { /// Button pressed down. /// ▼ * | * ▼ @@ -36,6 +38,7 @@ impl ButtonEvent { } #[derive(Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] pub enum TouchEvent { /// A person has started touching the screen at given absolute coordinates. /// `TouchMove` will usually follow, and `TouchEnd` should finish the @@ -61,6 +64,7 @@ impl TouchEvent { } #[derive(Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] pub enum USBEvent { /// USB host has connected/disconnected. Connected(bool), diff --git a/core/embed/rust/src/ui/geometry.rs b/core/embed/rust/src/ui/geometry.rs index d73702340..057b7e2c3 100644 --- a/core/embed/rust/src/ui/geometry.rs +++ b/core/embed/rust/src/ui/geometry.rs @@ -137,6 +137,7 @@ impl From for Offset { /// A point in 2D space defined by the the `x` and `y` coordinate. Relative /// coordinates, vectors, and offsets are represented by the `Offset` type. #[derive(Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] pub struct Point { pub x: i16, pub y: i16, diff --git a/core/embed/rust/src/ui/util.rs b/core/embed/rust/src/ui/util.rs index f3e4f33fb..7adc84701 100644 --- a/core/embed/rust/src/ui/util.rs +++ b/core/embed/rust/src/ui/util.rs @@ -21,8 +21,7 @@ impl ResultExt for Result { fn assert_if_debugging_ui(self, #[allow(unused)] message: &str) { #[cfg(feature = "ui_debug")] if self.is_err() { - print!("Panic from assert_if_debugging_ui: "); - println!(message); + println!("Panic from assert_if_debugging_ui: {}", message); panic!("{}", message); } }