Skip to content

Commit

Permalink
feat(core/rust/ui): return Layout results as singleton objects
Browse files Browse the repository at this point in the history
[no changelog]
  • Loading branch information
mmilata committed Mar 23, 2022
1 parent a5ef888 commit 2c3647d
Show file tree
Hide file tree
Showing 26 changed files with 453 additions and 312 deletions.
98 changes: 0 additions & 98 deletions core/embed/extmod/rustmods/modtrezorui2.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,104 +23,6 @@

#include "librust.h"

/// def layout_new_confirm_action(
/// *,
/// title: str,
/// action: str | None = None,
/// description: str | None = None,
/// verb: str | None = None,
/// verb_cancel: str | None = None,
/// hold: bool | None = None,
/// reverse: bool = False,
/// ) -> object:
/// """Example layout."""
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_trezorui2_layout_new_confirm_action_obj,
0, ui_layout_new_confirm_action);

#if TREZOR_MODEL == T
/// def layout_new_example(text: str) -> object:
/// """Example layout."""
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorui2_layout_new_example_obj,
ui_layout_new_example);

/// def layout_new_pin(
/// *,
/// prompt: str,
/// subprompt: str,
/// allow_cancel: bool,
/// warning: str | None,
/// ) -> object:
/// """PIN keyboard."""
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_trezorui2_layout_new_pin_obj, 0,
ui_layout_new_pin);

/// def layout_new_passphrase(
/// *,
/// prompt: str,
/// max_len: int,
/// ) -> object:
/// """Passphrase keyboard."""
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_trezorui2_layout_new_passphrase_obj, 0,
ui_layout_new_passphrase);

/// def layout_new_bip39(
/// *,
/// prompt: str,
/// ) -> object:
/// """BIP39 keyboard."""
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_trezorui2_layout_new_bip39_obj, 0,
ui_layout_new_bip39);

/// def layout_new_slip39(
/// *,
/// prompt: str,
/// ) -> object:
/// """BIP39 keyboard."""
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_trezorui2_layout_new_slip39_obj, 0,
ui_layout_new_slip39);
#elif TREZOR_MODEL == 1
/// def layout_new_confirm_text(
/// *,
/// title: str,
/// data: str,
/// description: str | None,
/// ) -> object:
/// """Example layout."""
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_trezorui2_layout_new_confirm_text_obj, 0,
ui_layout_new_confirm_text);
#endif

STATIC const mp_rom_map_elem_t mp_module_trezorui2_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorui2)},

{MP_ROM_QSTR(MP_QSTR_layout_new_confirm_action),
MP_ROM_PTR(&mod_trezorui2_layout_new_confirm_action_obj)},
#if TREZOR_MODEL == T
{MP_ROM_QSTR(MP_QSTR_layout_new_example),
MP_ROM_PTR(&mod_trezorui2_layout_new_example_obj)},
{MP_ROM_QSTR(MP_QSTR_layout_new_pin),
MP_ROM_PTR(&mod_trezorui2_layout_new_pin_obj)},
{MP_ROM_QSTR(MP_QSTR_layout_new_passphrase),
MP_ROM_PTR(&mod_trezorui2_layout_new_passphrase_obj)},
{MP_ROM_QSTR(MP_QSTR_layout_new_bip39),
MP_ROM_PTR(&mod_trezorui2_layout_new_bip39_obj)},
{MP_ROM_QSTR(MP_QSTR_layout_new_slip39),
MP_ROM_PTR(&mod_trezorui2_layout_new_slip39_obj)},
#elif TREZOR_MODEL == 1
{MP_ROM_QSTR(MP_QSTR_layout_new_confirm_text),
MP_ROM_PTR(&mod_trezorui2_layout_new_confirm_text_obj)},
#endif

};

STATIC MP_DEFINE_CONST_DICT(mp_module_trezorui2_globals,
mp_module_trezorui2_globals_table);

const mp_obj_module_t mp_module_trezorui2 = {
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mp_module_trezorui2_globals,
};

MP_REGISTER_MODULE(MP_QSTR_trezorui2, mp_module_trezorui2,
MICROPY_PY_TREZORUI2);

Expand Down
1 change: 1 addition & 0 deletions core/embed/rust/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ fn generate_micropython_bindings() {
.allowlist_function("mp_obj_new_int_from_uint")
.allowlist_function("mp_obj_new_bytes")
.allowlist_function("mp_obj_new_str")
.allowlist_function("mp_obj_new_tuple")
.allowlist_function("mp_obj_get_int_maybe")
.allowlist_function("mp_obj_is_true")
.allowlist_function("mp_call_function_n_kw")
Expand Down
14 changes: 1 addition & 13 deletions core/embed/rust/librust.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,7 @@ mp_obj_t protobuf_debug_msg_type();
mp_obj_t protobuf_debug_msg_def_type();
#endif

mp_obj_t ui_layout_new_example(mp_obj_t);
mp_obj_t ui_layout_new_confirm_action(size_t n_args, const mp_obj_t *args,
mp_map_t *kwargs);
mp_obj_t ui_layout_new_confirm_text(size_t n_args, const mp_obj_t *args,
mp_map_t *kwargs);
mp_obj_t ui_layout_new_pin(size_t n_args, const mp_obj_t *args,
mp_map_t *kwargs);
mp_obj_t ui_layout_new_passphrase(size_t n_args, const mp_obj_t *args,
mp_map_t *kwargs);
mp_obj_t ui_layout_new_bip39(size_t n_args, const mp_obj_t *args,
mp_map_t *kwargs);
mp_obj_t ui_layout_new_slip39(size_t n_args, const mp_obj_t *args,
mp_map_t *kwargs);
extern mp_obj_module_t mp_module_trezorui2;

#ifdef TREZOR_EMULATOR
mp_obj_t ui_debug_layout_type();
Expand Down
11 changes: 11 additions & 0 deletions core/embed/rust/librust_qstr.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,18 @@ static void _librust_qstrs(void) {
MP_QSTR_MESSAGE_NAME;

// layout
MP_QSTR___name__;
MP_QSTR_trezorui2;
MP_QSTR_Layout;
MP_QSTR_CONFIRMED;
MP_QSTR_CANCELLED;
MP_QSTR_confirm_action;
MP_QSTR_confirm_text;
MP_QSTR_request_pin;
MP_QSTR_request_passphrase;
MP_QSTR_request_bip39;
MP_QSTR_request_slip39;

MP_QSTR_set_timer_fn;
MP_QSTR_touch_event;
MP_QSTR_button_event;
Expand Down
1 change: 1 addition & 0 deletions core/embed/rust/src/micropython/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ macro_rules! obj_type {
macro_rules! obj_module {
($($key:expr => $val:expr),*) => ({
#[allow(unused_unsafe)]
#[allow(unused_doc_comments)]
unsafe {
use $crate::micropython::ffi;

Expand Down
17 changes: 17 additions & 0 deletions core/embed/rust/src/micropython/obj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,23 @@ impl TryFrom<&'static CStr> for Obj {
}
}

impl TryFrom<(Obj, Obj)> for Obj {
type Error = Error;

fn try_from(val: (Obj, Obj)) -> Result<Self, Self::Error> {
// SAFETY:
// - Should work with any micropython objects.
// EXCEPTION: Will raise if allocation fails.
let values = [val.0, val.1];
let obj = catch_exception(|| unsafe { ffi::mp_obj_new_tuple(2, values.as_ptr()) })?;
if obj.is_null() {
Err(Error::AllocationFailed)
} else {
Ok(obj)
}
}
}

//
// # Additional conversions based on the methods above.
//
Expand Down
2 changes: 1 addition & 1 deletion core/embed/rust/src/ui/geometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ impl Grid {
}

pub fn cells(&self, cells: GridCellSpan) -> Rect {
let from = self.row_col(cells.from.0, cells.to.1);
let from = self.row_col(cells.from.0, cells.from.1);
let to = self.row_col(cells.to.0, cells.to.1);
from.union(to)
}
Expand Down
1 change: 1 addition & 0 deletions core/embed/rust/src/ui/layout/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod obj;
pub mod result;
20 changes: 4 additions & 16 deletions core/embed/rust/src/ui/layout/obj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
},
time::Duration,
ui::{
component::{Child, Component, Event, EventCtx, Never, PageMsg, TimerToken},
component::{Child, Component, Event, EventCtx, Never, TimerToken},
geometry::Rect,
},
util,
Expand All @@ -38,13 +38,12 @@ pub trait ComponentMsgObj: Component {
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error>;
}

impl<T> ComponentMsgObj for T
impl<T> ComponentMsgObj for Child<T>
where
T: Component,
T::Msg: TryInto<Obj, Error = Error>,
T: ComponentMsgObj,
{
fn msg_try_into_obj(&self, msg: Self::Msg) -> Result<Obj, Error> {
msg.try_into()
self.inner().msg_try_into_obj(msg)
}
}

Expand Down Expand Up @@ -333,17 +332,6 @@ impl TryFrom<Duration> for Obj {
}
}

impl<T> TryFrom<PageMsg<T, bool>> for Obj {
type Error = Error;

fn try_from(val: PageMsg<T, bool>) -> Result<Self, Self::Error> {
match val {
PageMsg::Content(_) => Err(Error::TypeError),
PageMsg::Controls(c) => Ok(c.into()),
}
}
}

impl From<Never> for Obj {
fn from(_: Never) -> Self {
unreachable!()
Expand Down
34 changes: 34 additions & 0 deletions core/embed/rust/src/ui/layout/result.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use crate::micropython::{
obj::{Obj, ObjBase},
qstr::Qstr,
typ::Type,
};

#[repr(C)]
pub struct ResultObj {
base: ObjBase,
}

impl ResultObj {
/// Convert ResultObj to a MicroPython object.
pub const fn as_obj(&'static self) -> Obj {
// SAFETY:
// - We are an object struct with a base and a type.
// - 'static lifetime holds us in place.
// - There's nothing to mutate.
unsafe { Obj::from_ptr(self as *const _ as *mut _) }
}
}

// SAFETY: We are in a single-threaded environment.
unsafe impl Sync for ResultObj {}

static CONFIRMED_TYPE: Type = obj_type! { name: Qstr::MP_QSTR_CONFIRMED, };
static CANCELLED_TYPE: Type = obj_type! { name: Qstr::MP_QSTR_CANCELLED, };

pub static CONFIRMED: ResultObj = ResultObj {
base: CONFIRMED_TYPE.as_base(),
};
pub static CANCELLED: ResultObj = ResultObj {
base: CANCELLED_TYPE.as_base(),
};
4 changes: 4 additions & 0 deletions core/embed/rust/src/ui/model_t1/component/dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ where
right_btn: right.map(Child::new),
}
}

pub fn inner(&self) -> &T {
self.content.inner()
}
}

impl<T, U> Component for Dialog<T, U>
Expand Down
4 changes: 4 additions & 0 deletions core/embed/rust/src/ui/model_t1/component/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ where
content: Child::new(content),
}
}

pub fn inner(&self) -> &T {
self.content.inner()
}
}

impl<T, U> Component for Frame<T, U>
Expand Down
Loading

0 comments on commit 2c3647d

Please sign in to comment.