pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
// Required method
unsafe fn __init(self, slot: *mut T) -> Result<(), E>;
// Provided method
fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>
where F: FnOnce(&mut T) -> Result<(), E> { ... }
}
Expand description
An initializer for T
.
To use this initializer, you will need a suitable memory location that can hold a T
. This can
be Box<T>
, Arc<T>
, UniqueArc<T>
or even the stack (see stack_pin_init!
). Use the
InPlaceInit::init
function of a smart pointer like Arc<T>
on this. Because
PinInit<T, E>
is a super trait, you can use every function that takes it as well.
Also see the module description.
Safety
When implementing this type you will need to take great care. Also there are probably very few
cases where a manual implementation is necessary. Use init_from_closure
where possible.
The Init::__init
function
- returns
Ok(())
if it initialized every field ofslot
, - returns
Err(err)
if it encountered an error and then cleanedslot
, this means:slot
can be deallocated without UB occurring,slot
does not need to be dropped,slot
is not partially initialized.
- while constructing the
T
atslot
it upholds the pinning invariants ofT
.
The __pinned_init
function from the supertrait PinInit
needs to execute the exact same
code as __init
.
Contrary to its supertype PinInit<T, E>
the caller is allowed to
move the pointee after initialization.
Required Methods§
Provided Methods§
sourcefn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>where
F: FnOnce(&mut T) -> Result<(), E>,
fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>where F: FnOnce(&mut T) -> Result<(), E>,
First initializes the value using self
then calls the function f
with the initialized
value.
If f
returns an error the value is dropped and the initializer will forward the error.
Examples
use kernel::{types::Opaque, init::{self, init_from_closure}};
struct Foo {
buf: [u8; 1_000_000],
}
impl Foo {
fn setup(&mut self) {
pr_info!("Setting up foo");
}
}
let foo = init!(Foo {
buf <- init::zeroed()
}).chain(|foo| {
foo.setup();
Ok(())
});