6 releases (3 breaking)
0.4.0 | Jul 16, 2022 |
---|---|
0.3.1 | Jul 9, 2022 |
0.2.0 | Jul 8, 2022 |
0.1.1 | Jun 14, 2022 |
#2565 in Rust patterns
11KB
150 lines
Yet another pin projection helper macro
Creates zero-cost projection functions for pinned objects.
Example usage:
use pin_projections::project;
use std::pin::Pin;
// Just a placeholder for illustration
#[derive(Clone)]
struct Entry(u64);
// The structure to be projected
struct Example {
structural_pinned: Entry,
not_structural_pinned: Entry,
}
impl Example {
// The projections are defined within impl
// defining a projection for structural_pinned
// 1. for a pinned shared reference
project!(pub structural_pinned as first_entry() -> Pin<&Entry>);
// 2. and one for a pinned mutable reference.
project!(structural_pinned as first_entry_mut() -> Pin<&mut Entry>);
// 3. without the 'as function()' part the projection is named the same as the member
project!(pub structural_pinned -> Pin<&Entry>);
// When no projection name is given then mutable and immutable projections are
// mutually exclusive. The following would then collide with the definition #3 above.
// project!(structural_pinned -> Pin<&mut Entry>);
// 4. non structural pinned members are similar, just without the Pin<>
project!(not_structural_pinned as second_entry() -> &Entry);
// 5. one for a mutable reference.
project!(not_structural_pinned as second_entry_mut() -> &mut Entry);
// 6. all projections can be defined unsafe if necessary.
project!(pub(crate) unsafe structural_pinned as unsafe_projection() -> &mut Entry);
// 7. Types that are Clone can use a (cloning) getter.
project!(structural_pinned as get_first() -> Entry);
// 8. Types that are Clone you can use a borrowing setter.
project!(structural_pinned as set_first_from(&Entry));
// 9. Types that are not Clone can be set by a owning setter.
project!(structural_pinned as set_first_to(Entry));
}
fn main() {
let mut example = Box::pin(
Example{
structural_pinned: Entry(42),
not_structural_pinned: Entry(99),
}
);
// This is Pin<&Example>
let example_ref = example.as_ref();
// for 1.
assert_eq!(example_ref.first_entry().0, 42);
// for 3.
assert_eq!(example_ref.structural_pinned().0, 42);
// for 4.
assert_eq!(example_ref.second_entry().0, 99);
}