pub unsafe trait IoType {
type PointerType: TrivialType;
type WithLifetime<'b>: IoType<PointerType = Self::PointerType>;
type Reborrowed<'b>: BorrowMut<Self::WithLifetime<'b>>
where Self: 'b;
const METADATA: &[u8];
// Required methods
fn size(&self) -> u32;
fn capacity(&self) -> u32;
unsafe fn set_size(&mut self, size: u32);
unsafe fn from_ptr<'a>(
ptr: &'a NonNull<Self::PointerType>,
size: &'a u32,
capacity: u32,
) -> impl Deref<Target = Self::WithLifetime<'a>> + 'a;
unsafe fn from_mut_ptr<'a>(
ptr: &'a mut NonNull<Self::PointerType>,
size: &'a mut u32,
capacity: u32,
) -> impl DerefMut<Target = Self::WithLifetime<'a>> + 'a;
unsafe fn try_from_ptr<'a>(
ptr: &'a NonNull<Self::PointerType>,
size: &'a u32,
capacity: u32,
) -> Option<impl Deref<Target = Self::WithLifetime<'a>> + 'a>;
unsafe fn try_from_mut_ptr<'a>(
ptr: &'a mut NonNull<Self::PointerType>,
size: &'a mut u32,
capacity: u32,
) -> Option<impl DerefMut<Target = Self::WithLifetime<'a>> + 'a>;
fn as_ptr(&self) -> NonNull<Self::PointerType>;
fn as_mut_ptr(&mut self) -> NonNull<Self::PointerType>;
fn reborrow_mut(&mut self) -> Self::Reborrowed<'_>;
}Expand description
Trait that is used for types that are crossing the host/guest boundary in contracts.
Crucially, it is implemented for any type that implements TrivialType and for
VariableBytes.
§Safety
This trait is used for types with memory transmutation capabilities. Memory with untrusted
contents is parsed with IoType::try_from_ptr() and IoType::try_from_mut_ptr().
Serializing and deserializing of types that implement this trait is simply casting of underlying
memory. As a result, all the types implementing this trait must not use implicit padding,
unions, or anything similar that might make it unsound to access any bits of the type.
IoType::try_from_ptr() and IoType::try_from_mut_ptr() return Some only if
IoType::from_ptr() and IoType::from_mut_ptr() with the same arguments would be sound.
IoType::WithLifetime is the same type as Self, except that the memory it views, if any, is
borrowed for the lifetime it is given. IoType::reborrow_mut() returns self for types that
don’t view memory, and a new value that views the same memory for types that do.
Helper functions are provided to make casting to/from bytes a bit safer than it would otherwise, but extra care is still needed.
Do not implement this trait explicitly! Use #[derive(TrivialType)] instead, which will
ensure safety requirements are upheld, or use VariableBytes or other provided wrapper types if
more flexibility is needed.
In case of variable state size is needed, create a wrapper struct around VariableBytes and
implement traits on it by forwarding everything to the inner implementation, including
IoType::try_from_ptr() and IoType::try_from_mut_ptr().
Required Associated Constants§
Sourceconst METADATA: &[u8]
const METADATA: &[u8]
Data structure metadata in binary form, describing shape and types of the contents, see
IoTypeMetadataKind for encoding details
Required Associated Types§
Sourcetype PointerType: TrivialType
type PointerType: TrivialType
Pointer with a trivial type that this IoType represents
Sourcetype WithLifetime<'b>: IoType<PointerType = Self::PointerType>
type WithLifetime<'b>: IoType<PointerType = Self::PointerType>
The same type, viewing memory borrowed for 'b.
Containers like VariableElements view memory they don’t own and have a lifetime
parameter for it, which is 'b here. Types that don’t view memory, like those implementing
TrivialType, are Self.
Methods that create values from pointers and Self::reborrow_mut() return this type with
the lifetime of the borrow. So a container moved out of what they return, for example with
mem::swap(), can’t be used after the borrow ends, whatever lifetime Self has.
Sourcetype Reborrowed<'b>: BorrowMut<Self::WithLifetime<'b>>where
Self: 'b,
type Reborrowed<'b>: BorrowMut<Self::WithLifetime<'b>>where
Self: 'b,
Exclusive access to a value for 'b, which Self::reborrow_mut() returns.
This is &'b mut Self for types that don’t view memory, like those implementing
TrivialType, and Self::WithLifetime by value for containers. Generic code can get
&mut Self::WithLifetime<'b> from both with BorrowMut::borrow_mut().
Required Methods§
Sourceunsafe fn set_size(&mut self, size: u32)
unsafe fn set_size(&mut self, size: u32)
Set the number of used bytes.
§Safety
size must be valid for the type (see Self::try_from_ptr()) and not exceed the
capacity, and that many bytes must be initialized. They don’t need to be a valid value of
the type, but then the contents must not be accessed through this value until they are
parsed, for example with Self::try_from_mut_ptr().
Sourceunsafe fn from_ptr<'a>(
ptr: &'a NonNull<Self::PointerType>,
size: &'a u32,
capacity: u32,
) -> impl Deref<Target = Self::WithLifetime<'a>> + 'a
unsafe fn from_ptr<'a>( ptr: &'a NonNull<Self::PointerType>, size: &'a u32, capacity: u32, ) -> impl Deref<Target = Self::WithLifetime<'a>> + 'a
Create a reference to a type, which is represented by provided memory.
Memory must be correctly aligned and sufficient in size, but padding beyond the size of the type is allowed. Memory behind a pointer must not be written to in the meantime either.
Only size bytes are guaranteed to be allocated for types that can store a variable amount
of data due to the read-only nature of read-only access here.
§Safety
The memory holds a valid value of the type with a valid size, for example one that
Self::try_from_ptr() accepts.
Sourceunsafe fn from_mut_ptr<'a>(
ptr: &'a mut NonNull<Self::PointerType>,
size: &'a mut u32,
capacity: u32,
) -> impl DerefMut<Target = Self::WithLifetime<'a>> + 'a
unsafe fn from_mut_ptr<'a>( ptr: &'a mut NonNull<Self::PointerType>, size: &'a mut u32, capacity: u32, ) -> impl DerefMut<Target = Self::WithLifetime<'a>> + 'a
Create a mutable reference to a type, which is represented by provided memory.
Memory must be correctly aligned and sufficient in size, but padding beyond the size of the type is allowed. Memory behind a pointer must not be read or written to in the meantime either.
size indicates how many bytes are used within a larger allocation for types that can
store a variable amount of data.
§Safety
The memory holds a valid value of the type with a valid size, for example one that
Self::try_from_mut_ptr() accepts.
The returned value can be used for 'a. A container like VariableElements can also be
moved out of it, for example with mem::swap(), and then used until 'a ends. So the
memory must stay valid and must not be accessed otherwise until 'a ends, not only while
the returned value exists.
Sourceunsafe fn try_from_ptr<'a>(
ptr: &'a NonNull<Self::PointerType>,
size: &'a u32,
capacity: u32,
) -> Option<impl Deref<Target = Self::WithLifetime<'a>> + 'a>
unsafe fn try_from_ptr<'a>( ptr: &'a NonNull<Self::PointerType>, size: &'a u32, capacity: u32, ) -> Option<impl Deref<Target = Self::WithLifetime<'a>> + 'a>
Create a reference to a type, which is represented by provided memory, if the memory holds a valid value.
In contrast to Self::from_ptr(), the contents are checked, None is returned if the
first size bytes are not a valid value. Alignment, size and capacity are trusted like
in Self::from_ptr() and only checked with debug assertions.
§Safety
ptr is aligned for Self::PointerType, size doesn’t exceed capacity, and both are
valid for the type: size is the size of a TrivialType, 0 or the size of the data for
MaybeData and a multiple of the element size for VariableElements, and the capacity
of MaybeData is 0 or at least the size of the data. ptr is valid for reads of size
bytes, which are initialized and not written to during the call and while the returned value
exists.
Sourceunsafe fn try_from_mut_ptr<'a>(
ptr: &'a mut NonNull<Self::PointerType>,
size: &'a mut u32,
capacity: u32,
) -> Option<impl DerefMut<Target = Self::WithLifetime<'a>> + 'a>
unsafe fn try_from_mut_ptr<'a>( ptr: &'a mut NonNull<Self::PointerType>, size: &'a mut u32, capacity: u32, ) -> Option<impl DerefMut<Target = Self::WithLifetime<'a>> + 'a>
Like Self::try_from_ptr(), but returns an exclusive reference.
§Safety
ptr, size and capacity are valid as required by Self::try_from_ptr(), except that
the capacity of MaybeData is at least the size of the data, since data can be written
into it even if it is empty. ptr is valid for writes of capacity bytes and for reads of
the first size, which are initialized, while the bytes after them may be uninitialized.
The memory is not accessed otherwise during the call and while the returned value exists.
Like with Self::from_mut_ptr(), this lasts until 'a ends, since a container can be
moved out of the returned value.
Sourcefn as_ptr(&self) -> NonNull<Self::PointerType>
fn as_ptr(&self) -> NonNull<Self::PointerType>
Get a raw pointer to the underlying data.
The pointer can be used for reading Self::size() bytes as long as the value is not
modified, it must not be used for writing.
Sourcefn as_mut_ptr(&mut self) -> NonNull<Self::PointerType>
fn as_mut_ptr(&mut self) -> NonNull<Self::PointerType>
Get an exclusive raw pointer to the underlying data.
The pointer can be used for reading Self::size() bytes and writing up to
Self::capacity() bytes as long as the value is not accessed otherwise in the meantime.
Self::set_size() needs to be called afterward if the number of initialized bytes
changes.
Sourcefn reborrow_mut(&mut self) -> Self::Reborrowed<'_>
fn reborrow_mut(&mut self) -> Self::Reborrowed<'_>
Exclusive access to this value for the duration of the borrow.
For a container, this is a new view of the same memory with the lifetime of the borrow.
Replacing it doesn’t replace the container behind self, and it can’t be used after the
borrow ends. Types that don’t view memory return self.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".