mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-18 05:28:40 +00:00
refactor(core/rust): move iter_into_array to micropython::utils
This commit is contained in:
parent
3b88116bba
commit
8bf5a72843
@ -241,6 +241,8 @@ fn generate_micropython_bindings() {
|
||||
.allowlist_var("mp_type_module")
|
||||
// qstr
|
||||
.allowlist_function("qstr_data")
|
||||
// tuple
|
||||
.allowlist_type("mp_obj_tuple_t")
|
||||
// `ffi::mp_map_t` type is not allowed to be `Clone` or `Copy` because we tie it
|
||||
// to the data lifetimes with the `MapRef` type, see `src/micropython/map.rs`.
|
||||
// TODO: We should disable `Clone` and `Copy` for all types and only allow-list
|
||||
|
@ -2,5 +2,6 @@
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(clippy::unnecessary_cast)]
|
||||
#![allow(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/micropython.rs"));
|
||||
|
@ -1,13 +1,15 @@
|
||||
use core::slice;
|
||||
|
||||
use crate::{
|
||||
error::Error,
|
||||
micropython::{
|
||||
map::{Map, MapElem},
|
||||
obj::Obj,
|
||||
runtime::raise_exception,
|
||||
},
|
||||
use heapless::Vec;
|
||||
|
||||
use super::{
|
||||
ffi,
|
||||
iter::IterBuf,
|
||||
map::{Map, MapElem},
|
||||
obj::Obj,
|
||||
runtime::{catch_exception, raise_exception},
|
||||
};
|
||||
use crate::error::Error;
|
||||
|
||||
/// Perform a call and convert errors into a raised MicroPython exception.
|
||||
/// Should only called when returning from Rust to C. See `raise_exception` for
|
||||
@ -82,3 +84,34 @@ pub unsafe fn try_with_args_and_kwargs_inline(
|
||||
};
|
||||
unsafe { try_or_raise(block) }
|
||||
}
|
||||
|
||||
pub fn new_tuple(args: &[Obj]) -> Result<Obj, Error> {
|
||||
// SAFETY: Safe.
|
||||
// EXCEPTION: Raises if allocation fails, does not return NULL.
|
||||
let obj = catch_exception(|| unsafe { ffi::mp_obj_new_tuple(args.len(), args.as_ptr()) })?;
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
pub fn iter_into_array<T, E, const N: usize>(iterable: Obj) -> Result<[T; N], Error>
|
||||
where
|
||||
T: TryFrom<Obj, Error = E>,
|
||||
Error: From<E>,
|
||||
{
|
||||
let vec: Vec<T, N> = iter_into_vec(iterable)?;
|
||||
// Returns error if array.len() != N
|
||||
vec.into_array()
|
||||
.map_err(|_| value_error!("Invalid iterable length"))
|
||||
}
|
||||
|
||||
pub fn iter_into_vec<T, E, const N: usize>(iterable: Obj) -> Result<Vec<T, N>, Error>
|
||||
where
|
||||
T: TryFrom<Obj, Error = E>,
|
||||
Error: From<E>,
|
||||
{
|
||||
let mut vec = Vec::<T, N>::new();
|
||||
for item in IterBuf::new().try_iterate(iterable)? {
|
||||
vec.push(item.try_into()?)
|
||||
.map_err(|_| value_error!("Invalid iterable length"))?;
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
|
@ -3,10 +3,9 @@ use crate::{
|
||||
micropython::{
|
||||
buffer::{hexlify_bytes, StrBuffer},
|
||||
gc::Gc,
|
||||
iter::IterBuf,
|
||||
list::List,
|
||||
obj::Obj,
|
||||
util::try_or_raise,
|
||||
util::{iter_into_array, try_or_raise},
|
||||
},
|
||||
storage::{get_avatar_len, load_avatar},
|
||||
strutil::SkipPrefix,
|
||||
@ -18,31 +17,6 @@ use crate::{
|
||||
util::set_animation_disabled,
|
||||
},
|
||||
};
|
||||
use heapless::Vec;
|
||||
|
||||
pub fn iter_into_array<T, E, const N: usize>(iterable: Obj) -> Result<[T; N], Error>
|
||||
where
|
||||
T: TryFrom<Obj, Error = E>,
|
||||
Error: From<E>,
|
||||
{
|
||||
let vec: Vec<T, N> = iter_into_vec(iterable)?;
|
||||
// Returns error if array.len() != N
|
||||
vec.into_array()
|
||||
.map_err(|_| value_error!("Invalid iterable length"))
|
||||
}
|
||||
|
||||
pub fn iter_into_vec<T, E, const N: usize>(iterable: Obj) -> Result<Vec<T, N>, Error>
|
||||
where
|
||||
T: TryFrom<Obj, Error = E>,
|
||||
Error: From<E>,
|
||||
{
|
||||
let mut vec = Vec::<T, N>::new();
|
||||
for item in IterBuf::new().try_iterate(iterable)? {
|
||||
vec.push(item.try_into()?)
|
||||
.map_err(|_| value_error!("Invalid iterable length"))?;
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
|
||||
/// Maximum number of characters that can be displayed on screen at once. Used
|
||||
/// for on-the-fly conversion of binary data to hexadecimal representation.
|
||||
|
@ -38,7 +38,7 @@ use crate::{
|
||||
layout::{
|
||||
obj::{ComponentMsgObj, LayoutObj},
|
||||
result::{CANCELLED, CONFIRMED, INFO},
|
||||
util::{iter_into_array, iter_into_vec, upy_disable_animation, ConfirmBlob},
|
||||
util::{upy_disable_animation, ConfirmBlob},
|
||||
},
|
||||
model_tr::component::check_homescreen_format,
|
||||
},
|
||||
@ -380,7 +380,7 @@ extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *m
|
||||
let mut paragraphs = ParagraphVecLong::new();
|
||||
|
||||
for para in IterBuf::new().try_iterate(items)? {
|
||||
let [key, value, is_data]: [Obj; 3] = iter_into_array(para)?;
|
||||
let [key, value, is_data]: [Obj; 3] = util::iter_into_array(para)?;
|
||||
let key = key.try_into_option::<StrBuffer>()?;
|
||||
let value = value.try_into_option::<StrBuffer>()?;
|
||||
let is_data: bool = is_data.try_into()?;
|
||||
@ -506,7 +506,7 @@ extern "C" fn new_show_address_details(n_args: usize, args: *const Obj, kwargs:
|
||||
let mut ad = AddressDetails::new(address, case_sensitive, account, path)?;
|
||||
|
||||
for i in IterBuf::new().try_iterate(xpubs)? {
|
||||
let [xtitle, text]: [StrBuffer; 2] = iter_into_array(i)?;
|
||||
let [xtitle, text]: [StrBuffer; 2] = util::iter_into_array(i)?;
|
||||
ad.add_xpub(xtitle, text)?;
|
||||
}
|
||||
|
||||
@ -796,7 +796,7 @@ extern "C" fn new_altcoin_tx_summary(n_args: usize, args: *const Obj, kwargs: *m
|
||||
let mut ops = OpTextLayout::new(theme::TEXT_MONO);
|
||||
|
||||
for item in unwrap!(IterBuf::new().try_iterate(items)) {
|
||||
let [key, value]: [Obj; 2] = unwrap!(iter_into_array(item));
|
||||
let [key, value]: [Obj; 2] = unwrap!(util::iter_into_array(item));
|
||||
if !ops.is_empty() {
|
||||
// Each key-value pair is on its own page
|
||||
ops = ops.next_page();
|
||||
@ -1247,7 +1247,7 @@ extern "C" fn new_confirm_with_info(n_args: usize, args: *const Obj, kwargs: *mu
|
||||
let mut paragraphs = ParagraphVecShort::new();
|
||||
|
||||
for para in IterBuf::new().try_iterate(items)? {
|
||||
let [font, text]: [Obj; 2] = iter_into_array(para)?;
|
||||
let [font, text]: [Obj; 2] = util::iter_into_array(para)?;
|
||||
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
|
||||
let text: StrBuffer = text.try_into()?;
|
||||
paragraphs.add(Paragraph::new(style, text));
|
||||
@ -1278,7 +1278,7 @@ extern "C" fn new_confirm_more(n_args: usize, args: *const Obj, kwargs: *mut Map
|
||||
let mut paragraphs = ParagraphVecLong::new();
|
||||
|
||||
for para in IterBuf::new().try_iterate(items)? {
|
||||
let [font, text]: [Obj; 2] = iter_into_array(para)?;
|
||||
let [font, text]: [Obj; 2] = util::iter_into_array(para)?;
|
||||
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
|
||||
let text: StrBuffer = text.try_into()?;
|
||||
paragraphs.add(Paragraph::new(style, text));
|
||||
@ -1527,7 +1527,7 @@ extern "C" fn new_show_group_share_success(
|
||||
) -> Obj {
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
let lines_iterable: Obj = kwargs.get(Qstr::MP_QSTR_lines)?;
|
||||
let lines: [StrBuffer; 4] = iter_into_array(lines_iterable)?;
|
||||
let lines: [StrBuffer; 4] = util::iter_into_array(lines_iterable)?;
|
||||
|
||||
let [l0, l1, l2, l3] = lines;
|
||||
|
||||
|
@ -39,7 +39,7 @@ use crate::{
|
||||
layout::{
|
||||
obj::{ComponentMsgObj, LayoutObj},
|
||||
result::{CANCELLED, CONFIRMED, INFO},
|
||||
util::{iter_into_array, upy_disable_animation, ConfirmBlob, PropsList},
|
||||
util::{upy_disable_animation, ConfirmBlob, PropsList},
|
||||
},
|
||||
model_tt::component::check_homescreen_format,
|
||||
},
|
||||
@ -430,7 +430,7 @@ extern "C" fn new_confirm_emphasized(n_args: usize, args: *const Obj, kwargs: *m
|
||||
if item.is_str() {
|
||||
ops = ops.text_normal(item.try_into()?)
|
||||
} else {
|
||||
let [emphasis, text]: [Obj; 2] = iter_into_array(item)?;
|
||||
let [emphasis, text]: [Obj; 2] = util::iter_into_array(item)?;
|
||||
let text: StrBuffer = text.try_into()?;
|
||||
if emphasis.try_into()? {
|
||||
ops = ops.text_demibold(text);
|
||||
@ -721,7 +721,7 @@ extern "C" fn new_show_address_details(n_args: usize, args: *const Obj, kwargs:
|
||||
)?;
|
||||
|
||||
for i in IterBuf::new().try_iterate(xpubs)? {
|
||||
let [xtitle, text]: [StrBuffer; 2] = iter_into_array(i)?;
|
||||
let [xtitle, text]: [StrBuffer; 2] = util::iter_into_array(i)?;
|
||||
ad.add_xpub(xtitle, text)?;
|
||||
}
|
||||
|
||||
@ -741,7 +741,7 @@ extern "C" fn new_show_info_with_cancel(n_args: usize, args: *const Obj, kwargs:
|
||||
let mut paragraphs = ParagraphVecShort::new();
|
||||
|
||||
for para in IterBuf::new().try_iterate(items)? {
|
||||
let [key, value]: [Obj; 2] = iter_into_array(para)?;
|
||||
let [key, value]: [Obj; 2] = util::iter_into_array(para)?;
|
||||
let key: StrBuffer = key.try_into()?;
|
||||
let value: StrBuffer = value.try_into()?;
|
||||
paragraphs.add(Paragraph::new(&theme::TEXT_NORMAL, key).no_break());
|
||||
@ -806,7 +806,7 @@ extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Ma
|
||||
let mut paragraphs = ParagraphVecShort::new();
|
||||
|
||||
for pair in IterBuf::new().try_iterate(items)? {
|
||||
let [label, value]: [StrBuffer; 2] = iter_into_array(pair)?;
|
||||
let [label, value]: [StrBuffer; 2] = util::iter_into_array(pair)?;
|
||||
paragraphs.add(Paragraph::new(&theme::TEXT_NORMAL, label).no_break());
|
||||
paragraphs.add(Paragraph::new(&theme::TEXT_MONO, value));
|
||||
}
|
||||
@ -1165,7 +1165,7 @@ extern "C" fn new_confirm_with_info(n_args: usize, args: *const Obj, kwargs: *mu
|
||||
let mut paragraphs = ParagraphVecShort::new();
|
||||
|
||||
for para in IterBuf::new().try_iterate(items)? {
|
||||
let [font, text]: [Obj; 2] = iter_into_array(para)?;
|
||||
let [font, text]: [Obj; 2] = util::iter_into_array(para)?;
|
||||
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
|
||||
let text: StrBuffer = text.try_into()?;
|
||||
paragraphs.add(Paragraph::new(style, text));
|
||||
@ -1195,7 +1195,7 @@ extern "C" fn new_confirm_more(n_args: usize, args: *const Obj, kwargs: *mut Map
|
||||
let mut paragraphs = ParagraphVecLong::new();
|
||||
|
||||
for para in IterBuf::new().try_iterate(items)? {
|
||||
let [font, text]: [Obj; 2] = iter_into_array(para)?;
|
||||
let [font, text]: [Obj; 2] = util::iter_into_array(para)?;
|
||||
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
|
||||
let text: StrBuffer = text.try_into()?;
|
||||
paragraphs.add(Paragraph::new(style, text));
|
||||
@ -1290,7 +1290,7 @@ extern "C" fn new_select_word(n_args: usize, args: *const Obj, kwargs: *mut Map)
|
||||
let title: StrBuffer = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
|
||||
let description: StrBuffer = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
|
||||
let words_iterable: Obj = kwargs.get(Qstr::MP_QSTR_words)?;
|
||||
let words: [StrBuffer; 3] = iter_into_array(words_iterable)?;
|
||||
let words: [StrBuffer; 3] = util::iter_into_array(words_iterable)?;
|
||||
|
||||
let paragraphs = Paragraphs::new([Paragraph::new(&theme::TEXT_DEMIBOLD, description)]);
|
||||
let obj = LayoutObj::new(Frame::left_aligned(
|
||||
@ -1472,7 +1472,7 @@ extern "C" fn new_show_group_share_success(
|
||||
) -> Obj {
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
let lines_iterable: Obj = kwargs.get(Qstr::MP_QSTR_lines)?;
|
||||
let lines: [StrBuffer; 4] = iter_into_array(lines_iterable)?;
|
||||
let lines: [StrBuffer; 4] = util::iter_into_array(lines_iterable)?;
|
||||
|
||||
let obj = LayoutObj::new(IconDialog::new_shares(
|
||||
lines,
|
||||
@ -1493,7 +1493,7 @@ extern "C" fn new_show_remaining_shares(n_args: usize, args: *const Obj, kwargs:
|
||||
|
||||
let mut paragraphs = ParagraphVecLong::new();
|
||||
for page in IterBuf::new().try_iterate(pages_iterable)? {
|
||||
let [title, description]: [StrBuffer; 2] = iter_into_array(page)?;
|
||||
let [title, description]: [StrBuffer; 2] = util::iter_into_array(page)?;
|
||||
paragraphs
|
||||
.add(Paragraph::new(&theme::TEXT_DEMIBOLD, title))
|
||||
.add(Paragraph::new(&theme::TEXT_NORMAL, description).break_after());
|
||||
|
Loading…
Reference in New Issue
Block a user