From 32c3320f07a11e3f6011f5a34fa696e572ab2e8e Mon Sep 17 00:00:00 2001 From: matejcik Date: Wed, 9 Feb 2022 15:20:39 +0100 Subject: [PATCH] refactor(core/rust): pass around &str instead of [u8] in most places --- core/embed/rust/src/trezorhal/display.rs | 10 ++- core/embed/rust/src/ui/component/label.rs | 4 +- core/embed/rust/src/ui/component/paginated.rs | 4 +- .../rust/src/ui/component/text/formatted.rs | 77 ++++++++++--------- core/embed/rust/src/ui/component/text/iter.rs | 2 +- .../rust/src/ui/component/text/layout.rs | 38 ++++----- .../rust/src/ui/component/text/paragraphs.rs | 16 ++-- core/embed/rust/src/ui/display.rs | 10 ++- .../rust/src/ui/model_t1/component/button.rs | 6 +- .../rust/src/ui/model_t1/component/dialog.rs | 6 +- .../rust/src/ui/model_t1/component/frame.rs | 6 +- core/embed/rust/src/ui/model_t1/layout.rs | 30 ++++---- .../rust/src/ui/model_tt/component/button.rs | 8 +- .../rust/src/ui/model_tt/component/frame.rs | 6 +- .../ui/model_tt/component/keyboard/bip39.rs | 8 +- .../ui/model_tt/component/keyboard/common.rs | 15 ++-- .../model_tt/component/keyboard/mnemonic.rs | 13 ++-- .../model_tt/component/keyboard/passphrase.rs | 2 +- .../src/ui/model_tt/component/keyboard/pin.rs | 18 ++--- .../ui/model_tt/component/keyboard/slip39.rs | 13 ++-- .../rust/src/ui/model_tt/component/page.rs | 2 +- core/embed/rust/src/ui/model_tt/layout.rs | 36 ++++----- 22 files changed, 169 insertions(+), 161 deletions(-) diff --git a/core/embed/rust/src/trezorhal/display.rs b/core/embed/rust/src/trezorhal/display.rs index bba6527b6..f470b531d 100644 --- a/core/embed/rust/src/trezorhal/display.rs +++ b/core/embed/rust/src/trezorhal/display.rs @@ -67,7 +67,7 @@ pub fn backlight(val: i32) -> i32 { unsafe { display_backlight(val) } } -pub fn text(baseline_x: i32, baseline_y: i32, text: &[u8], font: i32, fgcolor: u16, bgcolor: u16) { +pub fn text(baseline_x: i32, baseline_y: i32, text: &str, font: i32, fgcolor: u16, bgcolor: u16) { unsafe { display_text( baseline_x, @@ -81,10 +81,16 @@ pub fn text(baseline_x: i32, baseline_y: i32, text: &[u8], font: i32, fgcolor: u } } -pub fn text_width(text: &[u8], font: i32) -> i32 { +pub fn text_width(text: &str, font: i32) -> i32 { unsafe { display_text_width(text.as_ptr() as _, text.len() as _, font) } } +pub fn char_width(ch: char, font: i32) -> i32 { + let mut buf = [0u8; 4]; + let encoding = ch.encode_utf8(&mut buf); + text_width(encoding, font) +} + pub fn text_height(font: i32) -> i32 { unsafe { display_text_height(font) } } diff --git a/core/embed/rust/src/ui/component/label.rs b/core/embed/rust/src/ui/component/label.rs index 68d31f56e..27ad2f1d1 100644 --- a/core/embed/rust/src/ui/component/label.rs +++ b/core/embed/rust/src/ui/component/label.rs @@ -21,7 +21,7 @@ pub struct Label { impl Label where - T: Deref, + T: Deref, { pub fn new(text: T, align: Alignment, style: LabelStyle) -> Self { Self { @@ -58,7 +58,7 @@ where impl Component for Label where - T: Deref, + T: Deref, { type Msg = Never; diff --git a/core/embed/rust/src/ui/component/paginated.rs b/core/embed/rust/src/ui/component/paginated.rs index 059b559fe..70f6ac17a 100644 --- a/core/embed/rust/src/ui/component/paginated.rs +++ b/core/embed/rust/src/ui/component/paginated.rs @@ -20,8 +20,8 @@ pub trait Paginate { impl Paginate for FormattedText where - F: AsRef<[u8]>, - T: AsRef<[u8]>, + F: AsRef, + T: AsRef, { fn page_count(&mut self) -> usize { let mut page_count = 1; // There's always at least one page. diff --git a/core/embed/rust/src/ui/component/text/formatted.rs b/core/embed/rust/src/ui/component/text/formatted.rs index 6944e8e30..f74486b7e 100644 --- a/core/embed/rust/src/ui/component/text/formatted.rs +++ b/core/embed/rust/src/ui/component/text/formatted.rs @@ -21,7 +21,7 @@ pub const MAX_ARGUMENTS: usize = 6; pub struct FormattedText { layout: TextLayout, format: F, - args: LinearMap<&'static [u8], T, MAX_ARGUMENTS>, + args: LinearMap<&'static str, T, MAX_ARGUMENTS>, char_offset: usize, } @@ -35,7 +35,7 @@ impl FormattedText { } } - pub fn with(mut self, key: &'static [u8], value: T) -> Self { + pub fn with(mut self, key: &'static str, value: T) -> Self { if self.args.insert(key, value).is_err() { #[cfg(feature = "ui_debug")] panic!("text args map is full"); @@ -83,18 +83,18 @@ impl FormattedText { impl FormattedText where - F: AsRef<[u8]>, - T: AsRef<[u8]>, + F: AsRef, + T: AsRef, { pub fn layout_content(&self, sink: &mut dyn LayoutSink) -> LayoutFit { let mut cursor = self.layout.initial_cursor(); let mut ops = Op::skip_n_text_bytes( Tokenizer::new(self.format.as_ref()).flat_map(|arg| match arg { Token::Literal(literal) => Some(Op::Text(literal)), - Token::Argument(b"mono") => Some(Op::Font(self.layout.mono_font)), - Token::Argument(b"bold") => Some(Op::Font(self.layout.bold_font)), - Token::Argument(b"normal") => Some(Op::Font(self.layout.normal_font)), - Token::Argument(b"medium") => Some(Op::Font(self.layout.medium_font)), + Token::Argument("mono") => Some(Op::Font(self.layout.mono_font)), + Token::Argument("bold") => Some(Op::Font(self.layout.bold_font)), + Token::Argument("normal") => Some(Op::Font(self.layout.normal_font)), + Token::Argument("medium") => Some(Op::Font(self.layout.medium_font)), Token::Argument(argument) => self .args .get(argument) @@ -108,8 +108,8 @@ where impl Component for FormattedText where - F: AsRef<[u8]>, - T: AsRef<[u8]>, + F: AsRef, + T: AsRef, { type Msg = Never; @@ -141,8 +141,8 @@ pub mod trace { impl<'a, F, T> crate::trace::Trace for TraceText<'a, F, T> where - F: AsRef<[u8]>, - T: AsRef<[u8]>, + F: AsRef, + T: AsRef, { fn trace(&self, d: &mut dyn crate::trace::Tracer) { self.0.layout_content(&mut TraceSink(d)); @@ -153,8 +153,8 @@ pub mod trace { #[cfg(feature = "ui_debug")] impl crate::trace::Trace for FormattedText where - F: AsRef<[u8]>, - T: AsRef<[u8]>, + F: AsRef, + T: AsRef, { fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.open("Text"); @@ -166,9 +166,9 @@ where #[derive(Copy, Clone, PartialEq, Eq)] pub enum Token<'a> { /// Process literal text content. - Literal(&'a [u8]), + Literal(&'a str), /// Process argument with specified descriptor. - Argument(&'a [u8]), + Argument(&'a str), } /// Processes a format string into an iterator of `Token`s. @@ -182,17 +182,18 @@ pub enum Token<'a> { /// assert!(matches!(parser.next(), Some(Token::Literal(", where you been?")))); /// ``` pub struct Tokenizer<'a> { - input: &'a [u8], + input: &'a str, inner: Peekable>>, } impl<'a> Tokenizer<'a> { /// Create a new tokenizer for bytes of a formatting string `input`, /// returning an iterator. - pub fn new(input: &'a [u8]) -> Self { + pub fn new(input: &'a str) -> Self { + assert!(input.is_ascii()); Self { input, - inner: input.iter().enumerate().peekable(), + inner: input.as_bytes().iter().enumerate().peekable(), } } } @@ -246,26 +247,26 @@ mod tests { #[test] fn tokenizer_yields_expected_tokens() { - assert!(Tokenizer::new(b"").eq([])); - assert!(Tokenizer::new(b"x").eq([Token::Literal(b"x")])); - assert!(Tokenizer::new(b"x\0y").eq([Token::Literal("x\0y".as_bytes())])); - assert!(Tokenizer::new(b"{").eq([])); - assert!(Tokenizer::new(b"x{").eq([Token::Literal(b"x")])); - assert!(Tokenizer::new(b"x{y").eq([Token::Literal(b"x")])); - assert!(Tokenizer::new(b"{}").eq([Token::Argument(b"")])); - assert!(Tokenizer::new(b"x{}y{").eq([ - Token::Literal(b"x"), - Token::Argument(b""), - Token::Literal(b"y"), + assert!(Tokenizer::new("").eq([])); + assert!(Tokenizer::new("x").eq([Token::Literal("x")])); + assert!(Tokenizer::new("x\0y").eq([Token::Literal("x\0y")])); + assert!(Tokenizer::new("{").eq([])); + assert!(Tokenizer::new("x{").eq([Token::Literal("x")])); + assert!(Tokenizer::new("x{y").eq([Token::Literal("x")])); + assert!(Tokenizer::new("{}").eq([Token::Argument("")])); + assert!(Tokenizer::new("x{}y{").eq([ + Token::Literal("x"), + Token::Argument(""), + Token::Literal("y"), ])); - assert!(Tokenizer::new(b"{\0}").eq([Token::Argument("\0".as_bytes()),])); - assert!(Tokenizer::new(b"{{y}").eq([Token::Argument(b"{y"),])); - assert!(Tokenizer::new(b"{{{{xyz").eq([])); - assert!(Tokenizer::new(b"x{}{{}}}}").eq([ - Token::Literal(b"x"), - Token::Argument(b""), - Token::Argument(b"{"), - Token::Literal(b"}}}"), + assert!(Tokenizer::new("{\0}").eq([Token::Argument("\0"),])); + assert!(Tokenizer::new("{{y}").eq([Token::Argument("{y"),])); + assert!(Tokenizer::new("{{{{xyz").eq([])); + assert!(Tokenizer::new("x{}{{}}}}").eq([ + Token::Literal("x"), + Token::Argument(""), + Token::Argument("{"), + Token::Literal("}}}"), ])); } } diff --git a/core/embed/rust/src/ui/component/text/iter.rs b/core/embed/rust/src/ui/component/text/iter.rs index fd99c5c79..5d148b899 100644 --- a/core/embed/rust/src/ui/component/text/iter.rs +++ b/core/embed/rust/src/ui/component/text/iter.rs @@ -169,7 +169,7 @@ trait GlyphMetrics { impl GlyphMetrics for Font { fn char_width(&self, ch: char) -> i32 { - self.text_width(&[ch as u8]) + Font::char_width(*self, ch) } fn line_height(&self) -> i32 { diff --git a/core/embed/rust/src/ui/component/text/layout.rs b/core/embed/rust/src/ui/component/text/layout.rs index 5e8a60009..38aa93fff 100644 --- a/core/embed/rust/src/ui/component/text/layout.rs +++ b/core/embed/rust/src/ui/component/text/layout.rs @@ -114,11 +114,11 @@ impl TextLayout { self.bounds.top_left() + Offset::y(self.text_font.text_height() + self.padding_top) } - pub fn fit_text(&self, text: &[u8]) -> LayoutFit { + pub fn fit_text(&self, text: &str) -> LayoutFit { self.layout_text(text, &mut self.initial_cursor(), &mut TextNoOp) } - pub fn render_text(&self, text: &[u8]) { + pub fn render_text(&self, text: &str) { self.layout_text(text, &mut self.initial_cursor(), &mut TextRenderer); } @@ -167,7 +167,7 @@ impl TextLayout { pub fn layout_text( &self, - text: &[u8], + text: &str, cursor: &mut Point, sink: &mut dyn LayoutSink, ) -> LayoutFit { @@ -276,7 +276,7 @@ impl LayoutFit { /// Visitor for text segment operations. pub trait LayoutSink { - fn text(&mut self, _cursor: Point, _layout: &TextLayout, _text: &[u8]) {} + fn text(&mut self, _cursor: Point, _layout: &TextLayout, _text: &str) {} fn hyphen(&mut self, _cursor: Point, _layout: &TextLayout) {} fn ellipsis(&mut self, _cursor: Point, _layout: &TextLayout) {} fn line_break(&mut self, _cursor: Point) {} @@ -290,7 +290,7 @@ impl LayoutSink for TextNoOp {} pub struct TextRenderer; impl LayoutSink for TextRenderer { - fn text(&mut self, cursor: Point, layout: &TextLayout, text: &[u8]) { + fn text(&mut self, cursor: Point, layout: &TextLayout, text: &str) { display::text( cursor, text, @@ -303,7 +303,7 @@ impl LayoutSink for TextRenderer { fn hyphen(&mut self, cursor: Point, layout: &TextLayout) { display::text( cursor, - b"-", + "-", layout.hyphen_font, layout.hyphen_color, layout.background_color, @@ -313,7 +313,7 @@ impl LayoutSink for TextRenderer { fn ellipsis(&mut self, cursor: Point, layout: &TextLayout) { display::text( cursor, - b"...", + "...", layout.ellipsis_font, layout.ellipsis_color, layout.background_color, @@ -330,8 +330,8 @@ pub mod trace { pub struct TraceSink<'a>(pub &'a mut dyn crate::trace::Tracer); impl<'a> LayoutSink for TraceSink<'a> { - fn text(&mut self, _cursor: Point, _layout: &TextLayout, text: &[u8]) { - self.0.bytes(text); + fn text(&mut self, _cursor: Point, _layout: &TextLayout, text: &str) { + self.0.string(text); } fn hyphen(&mut self, _cursor: Point, _layout: &TextLayout) { @@ -351,7 +351,7 @@ pub mod trace { #[derive(Copy, Clone, PartialEq, Eq)] pub enum Op<'a> { /// Render text with current color and font. - Text(&'a [u8]), + Text(&'a str), /// Set current text color. Color(Color), /// Set currently used font. @@ -396,22 +396,22 @@ struct Span { impl Span { fn fit_horizontally( - text: &[u8], + text: &str, max_width: i32, text_font: Font, hyphen_font: Font, breaking: LineBreaking, ) -> Self { - const ASCII_LF: u8 = b'\n'; - const ASCII_CR: u8 = b'\r'; - const ASCII_SPACE: u8 = b' '; - const ASCII_HYPHEN: u8 = b'-'; + const ASCII_LF: char = '\n'; + const ASCII_CR: char = '\r'; + const ASCII_SPACE: char = ' '; + const ASCII_HYPHEN: char = '-'; - fn is_whitespace(ch: u8) -> bool { + fn is_whitespace(ch: char) -> bool { ch == ASCII_SPACE || ch == ASCII_LF || ch == ASCII_CR } - let hyphen_width = hyphen_font.text_width(&[ASCII_HYPHEN]); + let hyphen_width = hyphen_font.char_width(ASCII_HYPHEN); // The span we return in case the line has to break. We mutate it in the // possible break points, and its initial value is returned in case no text @@ -427,8 +427,8 @@ impl Span { let mut span_width = 0; let mut found_any_whitespace = false; - for (i, &ch) in text.iter().enumerate() { - let char_width = text_font.text_width(&[ch]); + for (i, ch) in text.char_indices() { + let char_width = text_font.char_width(ch); // Consider if we could be breaking the line at this position. if is_whitespace(ch) { diff --git a/core/embed/rust/src/ui/component/text/paragraphs.rs b/core/embed/rust/src/ui/component/text/paragraphs.rs index dffacf27c..d45c945bb 100644 --- a/core/embed/rust/src/ui/component/text/paragraphs.rs +++ b/core/embed/rust/src/ui/component/text/paragraphs.rs @@ -29,7 +29,7 @@ pub struct Paragraphs { impl Paragraphs where - T: AsRef<[u8]>, + T: AsRef, { pub fn new() -> Self { Self { @@ -114,7 +114,7 @@ where impl Component for Paragraphs where - T: AsRef<[u8]>, + T: AsRef, { type Msg = Never; @@ -146,7 +146,7 @@ where impl Paginate for Paragraphs where - T: AsRef<[u8]>, + T: AsRef, { fn page_count(&mut self) -> usize { // There's always at least one page. @@ -175,7 +175,7 @@ pub mod trace { impl crate::trace::Trace for Paragraphs where - T: AsRef<[u8]>, + T: AsRef, { fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.open("Paragraphs"); @@ -201,20 +201,20 @@ pub struct Paragraph { impl Paragraph where - T: AsRef<[u8]>, + T: AsRef, { pub fn new(content: T, layout: TextLayout) -> Self { Self { content, layout } } - pub fn content(&self, char_offset: usize) -> &[u8] { + pub fn content(&self, char_offset: usize) -> &str { &self.content.as_ref()[char_offset..] } } impl Dimensions for Paragraph where - T: AsRef<[u8]>, + T: AsRef, { fn fit(&mut self, area: Rect) { self.layout.bounds = area; @@ -246,7 +246,7 @@ struct PageBreakIterator<'a, T> { /// `PageOffset { 0, 0 }` even if the paragraph vector is empty. impl<'a, T> Iterator for PageBreakIterator<'a, T> where - T: AsRef<[u8]>, + T: AsRef, { /// `PageOffset` denotes the first paragraph that is rendered and a /// character offset in that paragraph. diff --git a/core/embed/rust/src/ui/display.rs b/core/embed/rust/src/ui/display.rs index b6874cd0a..e128a492a 100644 --- a/core/embed/rust/src/ui/display.rs +++ b/core/embed/rust/src/ui/display.rs @@ -152,7 +152,7 @@ pub fn loader_indeterminate( ); } -pub fn text(baseline: Point, text: &[u8], font: Font, fg_color: Color, bg_color: Color) { +pub fn text(baseline: Point, text: &str, font: Font, fg_color: Color, bg_color: Color) { display::text( baseline.x, baseline.y, @@ -163,7 +163,7 @@ pub fn text(baseline: Point, text: &[u8], font: Font, fg_color: Color, bg_color: ); } -pub fn text_center(baseline: Point, text: &[u8], font: Font, fg_color: Color, bg_color: Color) { +pub fn text_center(baseline: Point, text: &str, font: Font, fg_color: Color, bg_color: Color) { let w = font.text_width(text); display::text( baseline.x - w / 2, @@ -183,10 +183,14 @@ impl Font { Self(id) } - pub fn text_width(self, text: &[u8]) -> i32 { + pub fn text_width(self, text: &str) -> i32 { display::text_width(text, self.0) } + pub fn char_width(self, ch: char) -> i32 { + display::char_width(ch, self.0) + } + pub fn text_height(self) -> i32 { display::text_height(self.0) } diff --git a/core/embed/rust/src/ui/model_t1/component/button.rs b/core/embed/rust/src/ui/model_t1/component/button.rs index 6d2b523db..3febad2ef 100644 --- a/core/embed/rust/src/ui/model_t1/component/button.rs +++ b/core/embed/rust/src/ui/model_t1/component/button.rs @@ -37,7 +37,7 @@ pub struct Button { state: State, } -impl> Button { +impl> Button { pub fn new(pos: ButtonPos, content: ButtonContent, styles: ButtonStyleSheet) -> Self { Self { pos, @@ -100,7 +100,7 @@ impl> Button { impl Component for Button where - T: AsRef<[u8]>, + T: AsRef, { type Msg = ButtonMsg; @@ -157,7 +157,7 @@ where #[cfg(feature = "ui_debug")] impl crate::trace::Trace for Button where - T: AsRef<[u8]> + crate::trace::Trace, + T: AsRef + crate::trace::Trace, { fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.open("Button"); diff --git a/core/embed/rust/src/ui/model_t1/component/dialog.rs b/core/embed/rust/src/ui/model_t1/component/dialog.rs index 3e39bca6e..5f1dd5a3c 100644 --- a/core/embed/rust/src/ui/model_t1/component/dialog.rs +++ b/core/embed/rust/src/ui/model_t1/component/dialog.rs @@ -22,7 +22,7 @@ pub struct Dialog { impl Dialog where T: Component, - U: AsRef<[u8]>, + U: AsRef, { pub fn new(content: T, left: Option>, right: Option>) -> Self { Self { @@ -40,7 +40,7 @@ where impl Component for Dialog where T: Component, - U: AsRef<[u8]>, + U: AsRef, { type Msg = DialogMsg; @@ -80,7 +80,7 @@ where impl crate::trace::Trace for Dialog where T: crate::trace::Trace, - U: crate::trace::Trace + AsRef<[u8]>, + U: crate::trace::Trace + AsRef, { fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.open("Dialog"); diff --git a/core/embed/rust/src/ui/model_t1/component/frame.rs b/core/embed/rust/src/ui/model_t1/component/frame.rs index 0ea55f538..f26447526 100644 --- a/core/embed/rust/src/ui/model_t1/component/frame.rs +++ b/core/embed/rust/src/ui/model_t1/component/frame.rs @@ -14,7 +14,7 @@ pub struct Frame { impl Frame where T: Component, - U: AsRef<[u8]>, + U: AsRef, { pub fn new(title: U, content: T) -> Self { Self { @@ -32,7 +32,7 @@ where impl Component for Frame where T: Component, - U: AsRef<[u8]>, + U: AsRef, { type Msg = T::Msg; @@ -68,7 +68,7 @@ where impl crate::trace::Trace for Frame where T: crate::trace::Trace, - U: crate::trace::Trace + AsRef<[u8]>, + U: crate::trace::Trace + AsRef, { fn trace(&self, t: &mut dyn crate::trace::Tracer) { t.open("Frame"); diff --git a/core/embed/rust/src/ui/model_t1/layout.rs b/core/embed/rust/src/ui/model_t1/layout.rs index 99e1cbafe..e4758bb08 100644 --- a/core/embed/rust/src/ui/model_t1/layout.rs +++ b/core/embed/rust/src/ui/model_t1/layout.rs @@ -2,7 +2,7 @@ use core::convert::TryInto; use crate::{ error::Error, - micropython::{buffer::Buffer, map::Map, module::Module, obj::Obj, qstr::Qstr}, + micropython::{buffer::StrBuffer, map::Map, module::Module, obj::Obj, qstr::Qstr}, ui::{ component::{ base::Component, @@ -39,7 +39,7 @@ where impl ComponentMsgObj for Frame where T: ComponentMsgObj, - U: AsRef<[u8]>, + U: AsRef, { fn msg_try_into_obj(&self, msg: Self::Msg) -> Result { self.inner().msg_try_into_obj(msg) @@ -48,12 +48,12 @@ where extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { let block = |_args: &[Obj], kwargs: &Map| { - let title: Buffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; - let action: Option = kwargs.get(Qstr::MP_QSTR_action)?.try_into_option()?; - let description: Option = + let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; + let action: Option = kwargs.get(Qstr::MP_QSTR_action)?.try_into_option()?; + let description: Option = kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?; - let verb: Option = kwargs.get(Qstr::MP_QSTR_verb)?.try_into_option()?; - let verb_cancel: Option = + let verb: Option = kwargs.get(Qstr::MP_QSTR_verb)?.try_into_option()?; + let verb_cancel: Option = kwargs.get(Qstr::MP_QSTR_verb_cancel)?.try_into_option()?; let reverse: bool = kwargs.get(Qstr::MP_QSTR_reverse)?.try_into()?; @@ -74,8 +74,8 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M title, ButtonPage::new( FormattedText::new::(format) - .with(b"action", action.unwrap_or_default()) - .with(b"description", description.unwrap_or_default()), + .with("action", action.unwrap_or_default()) + .with("description", description.unwrap_or_default()), theme::BG, ), ))?; @@ -86,9 +86,9 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M extern "C" fn new_confirm_text(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { let block = |_args: &[Obj], kwargs: &Map| { - let title: Buffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; - let data: Buffer = kwargs.get(Qstr::MP_QSTR_data)?.try_into()?; - let description: Option = + let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; + let data: StrBuffer = kwargs.get(Qstr::MP_QSTR_data)?.try_into()?; + let description: Option = kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?; let obj = LayoutObj::new(Frame::new( @@ -165,7 +165,7 @@ mod tests { impl ComponentMsgObj for Dialog where T: ComponentMsgObj, - U: AsRef<[u8]>, + U: AsRef, { fn msg_try_into_obj(&self, msg: Self::Msg) -> Result { match msg { @@ -182,7 +182,7 @@ mod tests { FormattedText::new::( "Testing text layout, with some text, and some more text. And {param}", ) - .with(b"param", b"parameters!"), + .with("param", "parameters!"), Some(Button::with_text( ButtonPos::Left, "Left", @@ -212,7 +212,7 @@ arameters! > left: