Expand description
§Projecture
This is in a proof of concept state and also internally uses a lot of not yet battle-tested unsafe code so use it on your own risk meanwhile if you are good with unsafe rust i would appreciate a soundness review
Allows to do almost arbitrary type projections. In comparison to other crates that do similar things it is more generic, does not require procedural macros and also does not impose additional requirements on target struct, if target struct is located in external crate that crate does not have to explicitly add a support for such projection(pin projection is an exception here).
Although as of now this crate doesn’t support enums yet, but it will be added later.
§Currently can do following type of projections
- Destructuring projection (similar to usual
let <pattern>
but also supports deref pattern, and also works if struct implementsDrop
which is just not called).
Note that due to limitations of declaration macros currently unmentioned fields will be leaked. - Reference(
&
,&mut
) projection (similar to match ergonomics inlet <pattern>
but also supports deref pattern) Pin
projectionCell
projectionMaybeUninit
projectionAtomic
(fromatomic
crate) projectionOption
projection (which works together with other kinds of projections)RefCell
guards projection- raw pointers projections (
*const T
,*mut T
,NonNull<T>
)
Also adds two types of projectable pointers:
generic::GenericPointer
- makes it possible to write code that is generic over the reference type.OwningRef
- reference that semantically owns data (sometimes referred as&own T
in various proposals). On nightly(withnightly
feature) it allows you to make object safe traits that acceptSelf
by value.
Where possible, projections can additionally project through a Deref
(including dereference by value via DerefOwned
).
Here is a general overview of what you can do, see project
! macro for more usage details.
struct Foo {
a: Bar,
b: Rc<Cell<Bar>>,
c: Pin<Box<Bar>>,
d: Atomic<Bar>,
}
struct Bar(usize,PhantomPinned);
// needed only for pin projections
pin_projectable!(Bar);
fn test(arg: &Foo) {
project!(
let Foo {
a: Bar (e, ..),
b: *Bar{ 0: cell },
c: *Bar (_, f) ,
d: Bar(atomic, ..),
} = arg);
let _: &usize = e;
let _: &Cell<usize> = cell;
let _: Pin<& PhantomPinned> = f;
let _: &Atomic<usize> = atomic;
let _: &usize = project!(arg -> a -> 0);
let _: &Cell<usize> = project!(arg -> b -> 0);
let _: Pin<& PhantomPinned> = project!(arg -> c -> 1);
let _: &Atomic<usize> = project!(arg -> d -> 0);
}
Also allows dependent crates to define their own projections via traits.
see atomic
module for example of how to do a projection of a transparent field wrapper
or Pin
for doing projections on a custom reference type
MSRV: 1.54
License: MIT
Re-exports§
pub use pin::*;
Modules§
Macros§
- PinProjectable
- Version of
pin_projectable
to work as derive macro withmacro_rules_attribute
- generic_
ptr - macro to create
GenericPointer
from regular references/pointers - pin_
projectable - Macro to delegate to
PinDrop
. - project
- Macro to do all kinds of projections
Structs§
- Drop
Leftovers - Keeps track of stuff that was left of
T
when we moved outT::Target
from it. - Marker
- Marker type for the projections used in this crate. You can use that if you need to reuse existing projections.
- Maybe
Deref Projectable - Option
Marker - Owning
Marker - Owning
Ref
Traits§
- Custom
Wrapper - Trait to, if necessary, transparently wrap type to prevent conflicting implementations
- Deref
Owned - Version of
Deref
trait that allows moving outSelf::Target
fromSelf
by value. - Deref
Projectable - Implement it if your projection can meaningfully project through a deref operation
- Finalize
Projection - Implement that if you need to do some kind of post processing like unwrap something or panic if some soundness requirements are not satisfied
- Projectable
- Trait to get raw pointer to underlying struct
- Projectable
Marker - Trait to wrap raw pointer to a field with a type that corresponds to a projection being done.
- Supports
Packed - Implement this only if your projection can work with
#[repr(packed)]
structs.