1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-20 06:28:09 +00:00

refactor(core/mercury): use params structs

Supply the rust layout with dedicated paremeter type instead of plain
micropython::Obj. The types used are ConfirmBlobParams and
ShowInfoParams.

[no changelog]
This commit is contained in:
obrusvit 2024-09-25 17:09:16 +02:00 committed by Vít Obrusník
parent 7cf38ec4c5
commit af554458b5
6 changed files with 151 additions and 142 deletions

View File

@ -38,6 +38,7 @@ static void _librust_qstrs(void) {
MP_QSTR___name__;
MP_QSTR_account;
MP_QSTR_account_items;
MP_QSTR_account_items_title;
MP_QSTR_account_label;
MP_QSTR_account_path;
MP_QSTR_accounts;

View File

@ -2,7 +2,6 @@ use heapless::Vec;
use crate::{
error,
micropython::{iter::IterBuf, obj::Obj, util},
strutil::TString,
translations::TR,
ui::{
@ -213,44 +212,30 @@ fn get_cancel_page(
#[allow(clippy::too_many_arguments)]
pub fn new_confirm_output(
title: Option<TString<'static>>,
subtitle: Option<TString<'static>>,
main_params: ConfirmBlobParams,
account: Option<TString<'static>>,
account_path: Option<TString<'static>>,
br_name: TString<'static>,
br_code: u16,
message: Obj,
amount: Option<Obj>,
chunkify: bool,
text_mono: bool,
address: Option<Obj>,
address_title: Option<TString<'static>>,
summary_items: Obj,
fee_items: Obj,
summary_title: Option<TString<'static>>,
content_amount_params: Option<ConfirmBlobParams>,
address_params: Option<ConfirmBlobParams>,
address_title: TString<'static>,
summary_items_params: Option<ShowInfoParams>,
fee_items_params: ShowInfoParams,
summary_br_name: Option<TString<'static>>,
summary_br_code: Option<u16>,
cancel_text: Option<TString<'static>>,
) -> Result<SwipeFlow, error::Error> {
// Main
let main_content = ConfirmBlobParams::new(title.unwrap_or(TString::empty()), message, None)
.with_subtitle(subtitle)
.with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None)
.with_chunkify(chunkify)
.with_text_mono(text_mono)
.with_swipe_up()
let main_content = main_params
.into_layout()?
.one_button_request(ButtonRequest::from_num(br_code, br_name));
// MainMenu
let mut main_menu = VerticalMenu::empty();
let mut main_menu_items = Vec::<usize, 3>::new();
if address.is_some() {
main_menu = main_menu.item(
theme::ICON_CHEVRON_RIGHT,
address_title.unwrap_or(TR::words__address.into()),
);
if address_params.is_some() {
main_menu = main_menu.item(theme::ICON_CHEVRON_RIGHT, address_title);
unwrap!(main_menu_items.push(MENU_ITEM_ADDRESS_INFO));
}
if account.is_some() && account_path.is_some() {
@ -280,17 +265,10 @@ pub fn new_confirm_output(
let ac = AddressDetails::new(TR::send__send_from.into(), account, account_path)?;
let account_content = ac.map(|_| Some(FlowMsg::Cancelled));
let res = if amount.is_some() {
let content_amount =
ConfirmBlobParams::new(TR::words__amount.into(), amount.unwrap(), None)
.with_subtitle(subtitle)
.with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None)
.with_text_mono(text_mono)
.with_swipe_up()
.with_swipe_down()
.into_layout()?
.one_button_request(ButtonRequest::from_num(br_code, br_name));
let res = if let Some(content_amount_params) = content_amount_params {
let content_amount = content_amount_params
.into_layout()?
.one_button_request(ButtonRequest::from_num(br_code, br_name));
SwipeFlow::new(&ConfirmOutputWithAmount::Address)?
.with_page(&ConfirmOutputWithAmount::Address, main_content)?
@ -298,19 +276,9 @@ pub fn new_confirm_output(
.with_page(&ConfirmOutputWithAmount::Menu, content_main_menu)?
.with_page(&ConfirmOutputWithAmount::AccountInfo, account_content)?
.with_page(&ConfirmOutputWithAmount::CancelTap, get_cancel_page())?
} else if summary_items != Obj::const_none() {
} else if let Some(summary_items_params) = summary_items_params {
// Summary
let mut summary =
ShowInfoParams::new(summary_title.unwrap_or(TR::words__title_summary.into()))
.with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None)
.with_swipe_up()
.with_swipe_down();
for pair in IterBuf::new().try_iterate(summary_items)? {
let [label, value]: [TString; 2] = util::iter_into_array(pair)?;
summary = unwrap!(summary.add(label, value));
}
let content_summary = summary
let content_summary = summary_items_params
.into_layout()?
.one_button_request(ButtonRequest::from_num(
summary_br_code.unwrap(),
@ -334,16 +302,8 @@ pub fn new_confirm_output(
});
// FeeInfo
let mut has_fee_info = false;
let mut fee = ShowInfoParams::new(TR::confirm_total__title_fee.into()).with_cancel_button();
if fee_items != Obj::const_none() {
for pair in IterBuf::new().try_iterate(fee_items)? {
let [label, value]: [TString; 2] = util::iter_into_array(pair)?;
fee = unwrap!(fee.add(label, value));
has_fee_info = true;
}
}
let content_fee = fee.into_layout()?;
let has_fee_info = !fee_items_params.is_empty();
let content_fee = fee_items_params.into_layout()?;
// SummaryMenu
let mut summary_menu = VerticalMenu::empty();
@ -390,17 +350,8 @@ pub fn new_confirm_output(
.with_page(&ConfirmOutputWithSummary::Main, main_content)?
.with_page(&ConfirmOutputWithSummary::MainMenu, content_main_menu)?
.with_page(&ConfirmOutputWithSummary::MainMenuCancel, get_cancel_page())?;
if address.is_some() {
let address_content = ConfirmBlobParams::new(
address_title.unwrap_or(TR::words__address.into()),
address.unwrap(),
None,
)
.with_cancel_button()
.with_chunkify(true)
.with_text_mono(true)
.with_swipe_right()
.into_layout()?;
if let Some(address_params) = address_params {
let address_content = address_params.into_layout()?;
flow = flow.with_page(&ConfirmOutputWithSummary::AddressInfo, address_content)?;
} else {
// dummy page - this will never be shown since there is no menu item pointing to

View File

@ -2,7 +2,6 @@ use heapless::Vec;
use crate::{
error,
micropython::{iter::IterBuf, obj::Obj, util},
strutil::TString,
translations::TR,
ui::{
@ -76,24 +75,15 @@ impl FlowController for ConfirmSummary {
}
pub fn new_confirm_summary(
title: TString<'static>,
items: Obj,
account_items: Obj,
fee_items: Obj,
summary_params: ShowInfoParams,
account_params: ShowInfoParams,
fee_params: ShowInfoParams,
br_name: TString<'static>,
br_code: u16,
cancel_text: Option<TString<'static>>,
) -> Result<SwipeFlow, error::Error> {
// Summary
let mut summary = ShowInfoParams::new(title)
.with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None)
.with_swipe_up();
for pair in IterBuf::new().try_iterate(items)? {
let [label, value]: [TString; 2] = util::iter_into_array(pair)?;
summary = unwrap!(summary.add(label, value));
}
let content_summary = summary
let content_summary = summary_params
.into_layout()?
.one_button_request(ButtonRequest::from_num(br_code, br_name))
// Summary(1) + Hold(1)
@ -115,24 +105,12 @@ pub fn new_confirm_summary(
});
// FeeInfo
let mut has_fee_info = false;
let mut fee = ShowInfoParams::new(TR::confirm_total__title_fee.into()).with_cancel_button();
for pair in IterBuf::new().try_iterate(fee_items)? {
let [label, value]: [TString; 2] = util::iter_into_array(pair)?;
fee = unwrap!(fee.add(label, value));
has_fee_info = true;
}
let content_fee = fee.into_layout()?;
let has_fee_info = !fee_params.is_empty();
let content_fee = fee_params.into_layout()?;
// AccountInfo
let mut has_account_info = false;
let mut account = ShowInfoParams::new(TR::send__send_from.into()).with_cancel_button();
for pair in IterBuf::new().try_iterate(account_items)? {
let [label, value]: [TString; 2] = util::iter_into_array(pair)?;
account = unwrap!(account.add(label, value));
has_account_info = true;
}
let content_account = account.into_layout()?;
let has_account_info = !account_params.is_empty();
let content_account = account_params.into_layout()?;
// Menu
let mut menu = VerticalMenu::empty();

View File

@ -307,6 +307,10 @@ impl ShowInfoParams {
}
}
pub fn is_empty(&self) -> bool {
self.items.is_empty()
}
#[inline(never)]
pub const fn with_subtitle(mut self, subtitle: Option<TString<'static>>) -> Self {
self.subtitle = subtitle;

View File

@ -63,7 +63,7 @@ pub fn new_warning_hi_prio(
value: TString<'static>,
verb_cancel: Option<TString<'static>>,
) -> Result<SwipeFlow, error::Error> {
let confirm: TString = TR::words__continue_anyway_question.into();
let confirm: TString = TR::words__continue_anyway.into();
let done_title: TString = TR::words__operation_cancelled.into();
let verb_cancel = verb_cancel.unwrap_or(TR::words__cancel_and_exit.into());

View File

@ -52,8 +52,11 @@ use crate::{
},
model_mercury::{
component::{check_homescreen_format, SwipeContent},
flow::util::ConfirmBlobParams,
flow::{new_confirm_action_simple, ConfirmActionMenu, ConfirmActionStrings},
flow::{
new_confirm_action_simple,
util::{ConfirmBlobParams, ShowInfoParams},
ConfirmActionMenu, ConfirmActionStrings,
},
theme::ICON_BULLET_CHECKMARK,
},
},
@ -301,26 +304,22 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
(description, &theme::TEXT_NORMAL)
};
ConfirmBlobParams::new(
title,
data,
description,
verb,
verb_info,
prompt_screen,
hold,
)
.with_description_font(description_font)
.with_text_mono(text_mono)
.with_subtitle(subtitle)
.with_verb_cancel(verb_cancel)
.with_extra(extra)
.with_info_button(info)
.with_chunkify(chunkify)
.with_page_limit(page_limit)
.into_flow()
.and_then(LayoutObj::new_root)
.map(Into::into)
ConfirmBlobParams::new(title, data, description)
.with_description_font(description_font)
.with_text_mono(text_mono)
.with_subtitle(subtitle)
.with_verb(verb)
.with_verb_cancel(verb_cancel)
.with_verb_info(verb_info)
.with_extra(extra)
.with_info_button(info)
.with_chunkify(chunkify)
.with_page_limit(page_limit)
.with_prompt(prompt_screen)
.with_hold(hold)
.into_flow()
.and_then(LayoutObj::new_root)
.map(Into::into)
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
@ -342,7 +341,7 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
let reverse: bool = kwargs.get_or(Qstr::MP_QSTR_reverse, false)?;
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let prompt_screen: bool = kwargs.get_or(Qstr::MP_QSTR_prompt_screen, false)?;
let prompt_title: TString = kwargs.get_or(Qstr::MP_QSTR_prompt_title, title.clone())?;
let prompt_title: TString = kwargs.get_or(Qstr::MP_QSTR_prompt_title, title)?;
let flow = flow::confirm_action::new_confirm_action(
title,
@ -535,8 +534,9 @@ extern "C" fn new_confirm_output(n_args: usize, args: *const Obj, kwargs: *mut M
let address_title: Option<TString> =
kwargs.get(Qstr::MP_QSTR_address_title)?.try_into_option()?;
let summary_items: Obj = kwargs.get(Qstr::MP_QSTR_summary_items)?;
let fee_items: Obj = kwargs.get(Qstr::MP_QSTR_fee_items)?;
let summary_items: Option<Obj> =
kwargs.get(Qstr::MP_QSTR_summary_items)?.try_into_option()?;
let fee_items: Option<Obj> = kwargs.get(Qstr::MP_QSTR_fee_items)?.try_into_option()?;
let summary_title: Option<TString> =
kwargs.get(Qstr::MP_QSTR_summary_title)?.try_into_option()?;
@ -547,25 +547,72 @@ extern "C" fn new_confirm_output(n_args: usize, args: *const Obj, kwargs: *mut M
.get(Qstr::MP_QSTR_summary_br_code)?
.try_into_option()?;
let address_title = address_title.unwrap_or(TR::words__address.into());
let cancel_text: Option<TString> =
kwargs.get(Qstr::MP_QSTR_cancel_text)?.try_into_option()?;
let main_params = ConfirmBlobParams::new(title.unwrap_or(TString::empty()), message, None)
.with_subtitle(subtitle)
.with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None)
.with_chunkify(chunkify)
.with_text_mono(text_mono)
.with_swipe_up();
let content_amount_params = amount.map(|amount| {
ConfirmBlobParams::new(TR::words__amount.into(), amount, None)
.with_subtitle(subtitle)
.with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None)
.with_text_mono(text_mono)
.with_swipe_up()
.with_swipe_down()
});
let address_params = address.map(|address| {
ConfirmBlobParams::new(address_title, address, None)
.with_cancel_button()
.with_chunkify(true)
.with_text_mono(true)
.with_swipe_right()
});
let mut fee_items_params =
ShowInfoParams::new(TR::confirm_total__title_fee.into()).with_cancel_button();
if fee_items.is_some() {
for pair in IterBuf::new().try_iterate(fee_items.unwrap())? {
let [label, value]: [TString; 2] = util::iter_into_array(pair)?;
fee_items_params = unwrap!(fee_items_params.add(label, value));
}
}
let summary_items_params: Option<ShowInfoParams> = if summary_items.is_some() {
let mut summary =
ShowInfoParams::new(summary_title.unwrap_or(TR::words__title_summary.into()))
.with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None)
.with_swipe_up()
.with_swipe_down();
for pair in IterBuf::new().try_iterate(summary_items.unwrap())? {
let [label, value]: [TString; 2] = util::iter_into_array(pair)?;
summary = unwrap!(summary.add(label, value));
}
Some(summary)
} else {
None
};
let flow = flow::confirm_output::new_confirm_output(
title,
subtitle,
main_params,
account,
account_path,
br_name,
br_code,
message,
amount,
chunkify,
text_mono,
address,
content_amount_params,
address_params,
address_title,
summary_items,
fee_items,
summary_title,
summary_items_params,
fee_items_params,
summary_br_name,
summary_br_code,
cancel_text,
@ -580,17 +627,44 @@ extern "C" fn new_confirm_summary(n_args: usize, args: *const Obj, kwargs: *mut
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let account_items: Obj = kwargs.get(Qstr::MP_QSTR_account_items)?;
let account_items_title: Option<TString> = kwargs
.get(Qstr::MP_QSTR_account_items_title)
.unwrap_or(Obj::const_none())
.try_into_option()?;
let fee_items: Obj = kwargs.get(Qstr::MP_QSTR_fee_items)?;
let br_name: TString = kwargs.get(Qstr::MP_QSTR_br_name)?.try_into()?;
let br_code: u16 = kwargs.get(Qstr::MP_QSTR_br_code)?.try_into()?;
let cancel_text: Option<TString> =
kwargs.get(Qstr::MP_QSTR_cancel_text)?.try_into_option()?;
let flow = flow::confirm_summary::new_confirm_summary(
title,
items,
account_items,
fee_items,
let mut summary_params = ShowInfoParams::new(title)
.with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None)
.with_swipe_up();
for pair in IterBuf::new().try_iterate(items)? {
let [label, value]: [TString; 2] = util::iter_into_array(pair)?;
summary_params = unwrap!(summary_params.add(label, value));
}
let mut account_params =
ShowInfoParams::new(account_items_title.unwrap_or(TR::send__send_from.into()))
.with_cancel_button();
for pair in IterBuf::new().try_iterate(account_items)? {
let [label, value]: [TString; 2] = util::iter_into_array(pair)?;
account_params = unwrap!(account_params.add(label, value));
}
let mut fee_params =
ShowInfoParams::new(TR::confirm_total__title_fee.into()).with_cancel_button();
for pair in IterBuf::new().try_iterate(fee_items)? {
let [label, value]: [TString; 2] = util::iter_into_array(pair)?;
fee_params = unwrap!(fee_params.add(label, value));
}
let flow = flow::new_confirm_summary(
summary_params,
account_params,
fee_params,
br_name,
br_code,
cancel_text,
@ -663,13 +737,13 @@ extern "C" fn new_confirm_value(n_args: usize, args: *const Obj, kwargs: *mut Ma
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
let text_mono: bool = kwargs.get_or(Qstr::MP_QSTR_text_mono, true)?;
ConfirmBlobParams::new(title, value, description, verb, None, hold, hold)
ConfirmBlobParams::new(title, value, description)
.with_subtitle(subtitle)
.with_verb(verb)
.with_verb_cancel(verb_cancel)
.with_info_button(info_button)
.with_chunkify(chunkify)
.with_text_mono(text_mono)
.with_verb_cancel(verb_cancel)
.with_prompt(hold)
.with_hold(hold)
.into_flow()
@ -1424,7 +1498,8 @@ extern "C" fn new_warning_hi_prio(n_args: usize, args: *const Obj, kwargs: *mut
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let flow = flow::warning_hi_prio::new_warning_hi_prio(title, description, value, verb_cancel)?;
let flow =
flow::warning_hi_prio::new_warning_hi_prio(title, description, value, verb_cancel)?;
Ok(LayoutObj::new_root(flow)?.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }