mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-28 00:01:31 +00:00
feat(core/rust): introduce StrBuffer
it is a variant of Buffer specifically for accepting python `str`
This commit is contained in:
parent
2ced50ed16
commit
785dc7f4d7
@ -72,6 +72,7 @@ fn generate_micropython_bindings() {
|
|||||||
.allowlist_var("MP_BUFFER_READ")
|
.allowlist_var("MP_BUFFER_READ")
|
||||||
.allowlist_var("MP_BUFFER_WRITE")
|
.allowlist_var("MP_BUFFER_WRITE")
|
||||||
.allowlist_var("MP_BUFFER_RW")
|
.allowlist_var("MP_BUFFER_RW")
|
||||||
|
.allowlist_var("mp_type_str")
|
||||||
// dict
|
// dict
|
||||||
.allowlist_type("mp_obj_dict_t")
|
.allowlist_type("mp_obj_dict_t")
|
||||||
.allowlist_function("mp_obj_new_dict")
|
.allowlist_function("mp_obj_new_dict")
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use core::{
|
use core::{
|
||||||
convert::TryFrom,
|
convert::TryFrom,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
ptr, slice,
|
ptr, slice, str,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{error::Error, micropython::obj::Obj};
|
use crate::{error::Error, micropython::obj::Obj};
|
||||||
@ -132,6 +132,50 @@ impl AsMut<[u8]> for BufferMut {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents an immutable UTF-8 string stored on the MicroPython heap and
|
||||||
|
/// owned by a `str` object.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// In most cases, it is unsound to store `StrBuffer` values in a GC-unreachable
|
||||||
|
/// location, such as static data. It is also unsound to let the contents be
|
||||||
|
/// modified while a reference to them is being held.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct StrBuffer(Buffer);
|
||||||
|
|
||||||
|
impl TryFrom<Obj> for StrBuffer {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(obj: Obj) -> Result<Self, Self::Error> {
|
||||||
|
if obj.is_qstr() || unsafe { ffi::mp_type_str.is_type_of(obj) } {
|
||||||
|
Ok(Self(Buffer::try_from(obj)?))
|
||||||
|
} else {
|
||||||
|
Err(Error::TypeError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for StrBuffer {
|
||||||
|
type Target = str;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<str> for StrBuffer {
|
||||||
|
fn as_ref(&self) -> &str {
|
||||||
|
// SAFETY: MicroPython ensures that values of type `str` are UTF-8
|
||||||
|
unsafe { str::from_utf8_unchecked(self.0.as_ref()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&'static str> for StrBuffer {
|
||||||
|
fn from(val: &'static str) -> Self {
|
||||||
|
Self(Buffer::from(val.as_bytes()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_buffer_info(obj: Obj, flags: u32) -> Result<ffi::mp_buffer_info_t, Error> {
|
fn get_buffer_info(obj: Obj, flags: u32) -> Result<ffi::mp_buffer_info_t, Error> {
|
||||||
let mut bufinfo = ffi::mp_buffer_info_t {
|
let mut bufinfo = ffi::mp_buffer_info_t {
|
||||||
buf: ptr::null_mut(),
|
buf: ptr::null_mut(),
|
||||||
@ -183,3 +227,10 @@ impl crate::trace::Trace for Buffer {
|
|||||||
self.as_ref().trace(t)
|
self.as_ref().trace(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ui_debug")]
|
||||||
|
impl crate::trace::Trace for StrBuffer {
|
||||||
|
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||||
|
self.as_ref().trace(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user