Crate projections
source · [−]Expand description
Safe structural pin projections without macros.
This like pin-project-lite but more lite.
Why
Because you want safe structural pin projections without macros for some reason.
Getting Started
Here’s an example of how you would create a public struct in your API that
uses pin projection internally via Sp
. This one goes out of it’s way
to not allocate (the allocating version is simpler).
mod lib {
use core::pin::Pin;
use projections::Sp;
// Sealed unique type to make namespace collisions impossible.
pub struct Seal;
pub type StructurallyPinnedStruct =
Sp<u32, String, Option<&'static [u8]>, Seal>;
pub struct StructurallyPinnedStructBuilder {
pub a: u32,
pub b: String,
pub c: Option<&'static [u8]>,
}
impl StructurallyPinnedStructBuilder {
pub fn build(self) -> StructurallyPinnedStruct {
let Self { a, b, c } = self;
Sp::from_a(a).with_b(b).with_c(c).with_d(Seal)
}
}
pub trait StructurallyPinnedStructApi {
fn use_pinned_types(self: Pin<&mut Self>);
}
impl StructurallyPinnedStructApi for StructurallyPinnedStruct {
fn use_pinned_types(mut self: Pin<&mut Self>) {
let _a: Pin<&mut u32> = self.as_mut().a();
let _b: Pin<&mut String> = self.as_mut().b();
let _c: Pin<&mut Option<&'static [u8]>> = self.as_mut().c();
}
}
}
use core::pin::Pin;
use lib::{StructurallyPinnedStructApi, StructurallyPinnedStructBuilder};
fn main() {
let mut structurally_pinned_struct = StructurallyPinnedStructBuilder {
a: 4,
b: "eight".to_string(),
c: Some(b"15"),
}
.build();
Pin::new(&mut structurally_pinned_struct).use_pinned_types();
}
Allocating Version
mod lib {
use core::pin::Pin;
use projections::Sp;
pub struct StructurallyPinnedStruct(
Pin<Box<Sp<u32, String, Option<&'static [u8]>>>>,
);
impl StructurallyPinnedStruct {
pub fn new(a: u32, b: String, c: Option<&'static [u8]>) -> Self {
let inner = Sp::from_a(a).with_b(b).with_c(c);
Self(Box::pin(inner))
}
pub fn use_pinned_types(&mut self) {
let _a: Pin<&mut u32> = self.0.as_mut().a();
let _b: Pin<&mut String> = self.0.as_mut().b();
let _c: Pin<&mut Option<&'static [u8]>> = self.0.as_mut().c();
}
}
}
use lib::StructurallyPinnedStruct;
fn main() {
let mut structurally_pinned_struct =
StructurallyPinnedStruct::new(4, "eight".to_string(), Some(b"15"));
structurally_pinned_struct.use_pinned_types();
}
Structs
Sp stands for Structurally Pinned