#![no_std]
#[cfg(test)]
extern crate alloc;
use core::pin::Pin;
#[doc(inline)]
pub use const_field_offset_macro::FieldOffsets;
pub use field_offset::{AllowPin, FieldOffset, NotPinned};
pub trait PinnedDrop {
fn drop(self: Pin<&mut Self>);
#[doc(hidden)]
fn do_safe_pinned_drop(&mut self) {
let p = unsafe { Pin::new_unchecked(self) };
p.drop()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate as const_field_offset;
#[derive(Debug, FieldOffsets)]
#[repr(C)]
struct Foo {
a: u32,
b: f64,
c: bool,
}
#[derive(Debug, FieldOffsets)]
#[repr(C)]
struct Bar {
x: u32,
y: Foo,
}
#[test]
#[allow(clippy::float_cmp)]
fn test_simple() {
let foo_b = Foo::FIELD_OFFSETS.b();
let mut x = Foo { a: 1, b: 2.0, c: false };
assert_eq!(*foo_b.apply(&x), 2.0);
*foo_b.apply_mut(&mut x) = 42.0;
assert_eq!(x.b, 42.0);
}
#[test]
#[allow(clippy::float_cmp)]
fn test_nested() {
let mut x = Bar { x: 0, y: Foo { a: 1, b: 2.0, c: false } };
let bar_y_b = Bar::FIELD_OFFSETS.y() + Foo::FIELD_OFFSETS.b();
*bar_y_b.apply_mut(&mut x) = 42.0;
assert_eq!(x.y.b, 42.0);
}
#[test]
#[allow(clippy::float_cmp)]
fn test_pin() {
use alloc::boxed::Box;
let foo_b = Foo::FIELD_OFFSETS.b();
let foo_b_pin = unsafe { foo_b.as_pinned_projection() };
let foo_object = Box::pin(Foo { a: 21, b: 22.0, c: true });
let pb: Pin<&f64> = foo_b_pin.apply_pin(foo_object.as_ref());
assert_eq!(*pb, 22.0);
let mut x = Box::pin(Bar { x: 0, y: Foo { a: 1, b: 52.0, c: false } });
let bar_y_b = Bar::FIELD_OFFSETS.y() + foo_b_pin;
assert_eq!(*bar_y_b.apply(&*x), 52.0);
let bar_y_pin = unsafe { Bar::FIELD_OFFSETS.y().as_pinned_projection() };
*(bar_y_pin + foo_b_pin).apply_pin_mut(x.as_mut()) = 12.;
assert_eq!(x.y.b, 12.0);
}
const _CONST_FOO_B: FieldOffset<Foo, f64> = Foo::FIELD_OFFSETS.b();
const _CONST_BAR_Y: FieldOffset<Bar, Foo> = Bar::FIELD_OFFSETS.y();
}
#[cfg(doctest)]
const NO_IMPL_UNPIN: u32 = 0;