#[macro_use]
mod macros;
pub use partial_ref_derive::PartialRefTarget;
use std::marker::PhantomData;
pub trait PartialRefTarget {
type RawTarget: ?Sized;
}
pub trait HasTarget {
type Target: PartialRefTarget + ?Sized;
}
pub trait PartialRef<'a>: HasTarget + Sized {
unsafe fn from_raw(ptr: *mut <Self::Target as PartialRefTarget>::RawTarget) -> Self;
fn get_raw(&self) -> *mut <Self::Target as PartialRefTarget>::RawTarget;
#[inline(always)]
fn borrow<BorrowedRef, SubsetIndex>(&'a mut self) -> BorrowedRef
where
BorrowedRef: PartialRef<'a, Target = Self::Target>,
Self: HasSubset<'a, BorrowedRef, SubsetIndex>,
{
unsafe { BorrowedRef::from_raw(self.get_raw()) }
}
#[inline(always)]
fn part<FieldPartSpec, FieldPart, PartIndex, FieldType>(
&'a self,
_part: FieldPartSpec,
) -> &'a FieldType
where
FieldType: ?Sized,
FieldPart: Part<PartType = Field<FieldType>>,
FieldPartSpec: PartSpec<FieldPart>,
Self: PluckConst<'a, FieldPart, PartIndex>,
Self::Target: HasPart<FieldPart> + 'a,
{
unsafe {
<Const<FieldPart, Ref<'a, Self::Target>> as PartialRef<'a>>::from_raw(self.get_raw())
.get_part()
}
}
#[inline(always)]
fn part_mut<FieldPartSpec, FieldPart, PartIndex, FieldType>(
&'a mut self,
_part: FieldPartSpec,
) -> &'a mut FieldType
where
FieldType: ?Sized,
FieldPart: Part<PartType = Field<FieldType>>,
FieldPartSpec: PartSpec<FieldPart>,
Self: PluckMut<'a, FieldPart, PartIndex>,
Self::Target: HasPart<FieldPart> + 'a,
{
unsafe {
<Mut<FieldPart, Ref<'a, Self::Target>> as PartialRef<'a>>::from_raw(self.get_raw())
.get_part_mut()
}
}
#[inline(always)]
fn split_borrow<BorrowedRef, SubsetIndex>(&'a mut self) -> (BorrowedRef, Self::Remainder)
where
BorrowedRef: PartialRef<'a, Target = Self::Target>,
Self: HasSubset<'a, BorrowedRef, SubsetIndex>,
{
let ptr = self.get_raw();
unsafe { (BorrowedRef::from_raw(ptr), Self::Remainder::from_raw(ptr)) }
}
#[inline(always)]
fn split_part<FieldPartSpec, FieldPart, PartIndex, FieldType>(
&'a mut self,
_part: FieldPartSpec,
) -> (&'a FieldType, Self::Remainder)
where
FieldType: ?Sized,
FieldPart: Part<PartType = Field<FieldType>>,
FieldPartSpec: PartSpec<FieldPart>,
Self: PluckConst<'a, FieldPart, PartIndex>,
Self::Target: HasPart<FieldPart> + 'a,
{
let ptr = self.get_raw();
unsafe {
(
<Const<FieldPart, Ref<'a, Self::Target>> as PartialRef<'a>>::from_raw(ptr)
.get_part(),
Self::Remainder::from_raw(ptr),
)
}
}
#[inline(always)]
fn split_part_mut<FieldPartSpec, FieldPart, PartIndex, FieldType>(
&'a mut self,
_part: FieldPartSpec,
) -> (&'a mut FieldType, Self::Remainder)
where
FieldType: ?Sized,
FieldPart: Part<PartType = Field<FieldType>>,
FieldPartSpec: PartSpec<FieldPart>,
Self: PluckMut<'a, FieldPart, PartIndex>,
Self::Target: HasPart<FieldPart> + 'a,
{
let ptr = self.get_raw();
unsafe {
(
<Mut<FieldPart, Ref<'a, Self::Target>> as PartialRef<'a>>::from_raw(ptr)
.get_part_mut(),
Self::Remainder::from_raw(ptr),
)
}
}
}
pub trait IntoPartialRef<'a> {
type Ref: PartialRef<'a>;
fn into_partial_ref(self) -> Self::Ref;
}
pub trait IntoPartialRefMut<'a>: IntoPartialRef<'a> {
fn into_partial_ref_mut(self) -> Self::Ref;
}
impl<'a, T> IntoPartialRefMut<'a> for &'a mut T
where
Self: IntoPartialRef<'a>,
{
fn into_partial_ref_mut(self) -> Self::Ref {
self.into_partial_ref()
}
}
pub unsafe trait SplitIntoParts<'a, ContainingPart, Reference: PartialRef<'a>> {
type Result: PartialRef<'a, Target = Reference::Target>;
type ResultMut: PartialRef<'a, Target = Reference::Target>;
}
#[repr(transparent)]
pub struct Ref<'a, Target: PartialRefTarget + ?Sized> {
ptr: *mut Target::RawTarget,
phantom: PhantomData<&'a mut Target>,
}
impl<'a, Target: PartialRefTarget + ?Sized> HasTarget for Ref<'a, Target> {
type Target = Target;
}
impl<'a, 'b: 'a, Target: PartialRefTarget + ?Sized> PartialRef<'a> for Ref<'b, Target> {
#[inline(always)]
unsafe fn from_raw(ptr: *mut <Self::Target as PartialRefTarget>::RawTarget) -> Self {
Ref {
ptr,
phantom: PhantomData,
}
}
#[inline(always)]
fn get_raw(&self) -> *mut <Self::Target as PartialRefTarget>::RawTarget {
self.ptr
}
}
impl<'a, Target: PartialRefTarget> Copy for Ref<'a, Target> {}
impl<'a, Target: PartialRefTarget> Clone for Ref<'a, Target> {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}
#[repr(transparent)]
pub struct Mut<Part, Reference: HasTarget> {
ptr: *mut <<Reference as HasTarget>::Target as PartialRefTarget>::RawTarget,
phantom: PhantomData<(Reference, Part)>,
}
impl<'a, SomePart: Part, Reference: PartialRef<'a>> HasTarget for Mut<SomePart, Reference>
where
Reference::Target: HasPart<SomePart>,
{
type Target = Reference::Target;
}
impl<'a, SomePart: Part, Reference: PartialRef<'a>> PartialRef<'a> for Mut<SomePart, Reference>
where
Reference::Target: HasPart<SomePart>,
{
#[inline(always)]
unsafe fn from_raw(ptr: *mut <Self::Target as PartialRefTarget>::RawTarget) -> Self {
Mut {
ptr,
phantom: PhantomData,
}
}
#[inline(always)]
fn get_raw(&self) -> *mut <Self::Target as PartialRefTarget>::RawTarget {
self.ptr
}
}
#[repr(transparent)]
pub struct Const<Part, Reference: HasTarget> {
ptr: *mut <<Reference as HasTarget>::Target as PartialRefTarget>::RawTarget,
phantom: PhantomData<(Reference, Part)>,
}
impl<'a, SomePart: Part, Reference: PartialRef<'a>> HasTarget for Const<SomePart, Reference>
where
Reference::Target: HasPart<SomePart>,
{
type Target = Reference::Target;
}
impl<'a, SomePart: Part, Reference: PartialRef<'a>> PartialRef<'a> for Const<SomePart, Reference>
where
Reference::Target: HasPart<SomePart>,
{
#[inline(always)]
unsafe fn from_raw(ptr: *mut <Self::Target as PartialRefTarget>::RawTarget) -> Self {
Const {
ptr,
phantom: PhantomData,
}
}
#[inline(always)]
fn get_raw(&self) -> *mut <Self::Target as PartialRefTarget>::RawTarget {
self.ptr
}
}
impl<SomePart, Reference: Copy + HasTarget> Copy for Const<SomePart, Reference> {}
impl<SomePart, Reference: Copy + HasTarget> Clone for Const<SomePart, Reference> {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}
impl<'a, SomePart, Target, FieldType> Const<SomePart, Ref<'a, Target>>
where
FieldType: ?Sized,
SomePart: Part<PartType = Field<FieldType>>,
Target: ?Sized,
Target: HasPart<SomePart>,
{
#[inline(always)]
fn get_part(self) -> &'a FieldType {
unsafe { &*Target::part_ptr(self.get_raw() as *const _) }
}
}
impl<'a, SomePart, Target, FieldType> Mut<SomePart, Ref<'a, Target>>
where
FieldType: ?Sized,
SomePart: Part<PartType = Field<FieldType>>,
Target: ?Sized,
Target: HasPart<SomePart>,
{
#[inline(always)]
fn get_part_mut(self) -> &'a mut FieldType {
unsafe { &mut *Target::part_ptr_mut(self.get_raw()) }
}
}
pub trait Part: Default {
type PartType: PartType;
}
pub trait PartSpec<Part> {}
pub trait HasPart<SomePart: Part>: PartialRefTarget {
unsafe fn part_ptr(ptr: *const Self::RawTarget) -> <SomePart::PartType as PartType>::Ptr;
unsafe fn part_ptr_mut(ptr: *mut Self::RawTarget) -> <SomePart::PartType as PartType>::PtrMut;
}
pub trait PartType {
type Ptr;
type PtrMut;
}
pub struct Field<FieldType: ?Sized>(PhantomData<FieldType>);
impl<FieldType: ?Sized> PartType for Field<FieldType> {
type Ptr = *const FieldType;
type PtrMut = *mut FieldType;
}
pub struct AbstractPart;
impl PartType for AbstractPart {
type Ptr = ();
type PtrMut = ();
}
#[derive(Default)]
pub struct Nested<Outer, Inner>(Outer, Inner);
impl<NewInnerPart: Part, Outer: Part, Inner: Part> std::ops::BitOr<NewInnerPart>
for Nested<Outer, Inner>
{
type Output = Nested<Nested<Outer, Inner>, NewInnerPart>;
fn bitor(self, _rhs: NewInnerPart) -> Self::Output {
std::default::Default::default()
}
}
impl<Outer, OuterFieldType, Inner> Part for Nested<Outer, Inner>
where
Outer: Part<PartType = Field<OuterFieldType>>,
Inner: Part,
OuterFieldType: ?Sized,
OuterFieldType: HasPart<Inner>,
OuterFieldType: PartialRefTarget<RawTarget = OuterFieldType>,
{
type PartType = Inner::PartType;
}
impl<Outer, Inner, OuterS, InnerS> PartSpec<Nested<OuterS, InnerS>> for Nested<Outer, Inner>
where
Outer: PartSpec<OuterS>,
Inner: PartSpec<InnerS>,
{
}
impl<Reference, Outer, OuterFieldType, Inner> HasPart<Nested<Outer, Inner>> for Reference
where
Reference: ?Sized,
Reference: HasPart<Outer>,
Outer: Part<PartType = Field<OuterFieldType>>,
Inner: Part,
OuterFieldType: ?Sized,
OuterFieldType: HasPart<Inner>,
OuterFieldType: PartialRefTarget<RawTarget = OuterFieldType>,
{
#[inline(always)]
unsafe fn part_ptr(ptr: *const Self::RawTarget) -> <Inner::PartType as PartType>::Ptr {
<OuterFieldType as HasPart<Inner>>::part_ptr(<Self as HasPart<Outer>>::part_ptr(ptr))
}
#[inline(always)]
unsafe fn part_ptr_mut(ptr: *mut Self::RawTarget) -> <Inner::PartType as PartType>::PtrMut {
<OuterFieldType as HasPart<Inner>>::part_ptr_mut(<Self as HasPart<Outer>>::part_ptr_mut(
ptr,
))
}
}
pub struct IndexHere;
pub struct IndexNext<Index>(Index);
pub struct IndexSplit<NestedPartIndex, Index>(NestedPartIndex, Index);
pub unsafe trait PluckConst<'a, PluckedPart, Index>: PartialRef<'a> {
type Remainder: PartialRef<'a, Target = Self::Target>;
}
pub unsafe trait PluckMut<'a, PluckedPart, Index>: PartialRef<'a> {
type Remainder: PartialRef<'a, Target = Self::Target>;
}
unsafe impl<'a, PluckedPart, Reference> PluckConst<'a, PluckedPart, IndexHere>
for Const<PluckedPart, Reference>
where
PluckedPart: Part,
Reference: PartialRef<'a>,
Reference::Target: HasPart<PluckedPart>,
{
type Remainder = Const<PluckedPart, Reference>;
}
unsafe impl<'a, PluckedPart, Reference> PluckConst<'a, PluckedPart, IndexHere>
for Mut<PluckedPart, Reference>
where
PluckedPart: Part,
Reference: PartialRef<'a>,
Reference::Target: HasPart<PluckedPart>,
{
type Remainder = Const<PluckedPart, Reference>;
}
unsafe impl<'a, PluckedPart, Reference> PluckMut<'a, PluckedPart, IndexHere>
for Mut<PluckedPart, Reference>
where
PluckedPart: Part,
Reference: PartialRef<'a>,
Reference::Target: HasPart<PluckedPart>,
{
type Remainder = Reference;
}
unsafe impl<'a, PluckedPart, SkippedPart, Reference, Index>
PluckConst<'a, PluckedPart, IndexNext<Index>> for Const<SkippedPart, Reference>
where
PluckedPart: Part,
SkippedPart: Part,
Reference::Target: HasPart<PluckedPart>,
Reference::Target: HasPart<SkippedPart>,
Reference: PluckConst<'a, PluckedPart, Index>,
{
type Remainder = Const<SkippedPart, Reference::Remainder>;
}
unsafe impl<'a, PluckedPart, SkippedPart, Reference, Index>
PluckConst<'a, PluckedPart, IndexNext<Index>> for Mut<SkippedPart, Reference>
where
PluckedPart: Part,
SkippedPart: Part,
Reference::Target: HasPart<PluckedPart>,
Reference::Target: HasPart<SkippedPart>,
Reference: PluckConst<'a, PluckedPart, Index>,
{
type Remainder = Mut<SkippedPart, Reference::Remainder>;
}
unsafe impl<'a, PluckedPart, SkippedPart, Reference, Index>
PluckMut<'a, PluckedPart, IndexNext<Index>> for Const<SkippedPart, Reference>
where
PluckedPart: Part,
SkippedPart: Part,
Reference::Target: HasPart<PluckedPart>,
Reference::Target: HasPart<SkippedPart>,
Reference: PluckMut<'a, PluckedPart, Index>,
{
type Remainder = Const<SkippedPart, Reference::Remainder>;
}
unsafe impl<'a, PluckedPart, SkippedPart, Reference, Index>
PluckMut<'a, PluckedPart, IndexNext<Index>> for Mut<SkippedPart, Reference>
where
PluckedPart: Part,
SkippedPart: Part,
Reference::Target: HasPart<PluckedPart>,
Reference::Target: HasPart<SkippedPart>,
Reference: PluckMut<'a, PluckedPart, Index>,
{
type Remainder = Mut<SkippedPart, Reference::Remainder>;
}
unsafe impl<
'a,
ContainingPart,
PluckedOuter,
PluckedInner,
Reference,
NestedPartIndex,
Index,
OuterFieldType,
ContainingFieldType,
> PluckMut<'a, Nested<PluckedOuter, PluckedInner>, IndexSplit<NestedPartIndex, Index>>
for Mut<ContainingPart, Reference>
where
PluckedOuter: Part<PartType = Field<OuterFieldType>>,
PluckedInner: Part,
ContainingPart: Part<PartType = Field<ContainingFieldType>>,
ContainingFieldType: SplitIntoParts<'a, ContainingPart, Reference>,
ContainingFieldType: ?Sized,
ContainingFieldType::ResultMut: PluckMut<'a, Nested<PluckedOuter, PluckedInner>, Index>,
OuterFieldType: ?Sized,
OuterFieldType: HasPart<PluckedInner>,
OuterFieldType: PartialRefTarget<RawTarget = OuterFieldType>,
Reference: PartialRef<'a>,
Reference::Target: HasPart<ContainingPart>,
ContainingPart: ContainsNestedPart<PluckedOuter, NestedPartIndex>,
{
type Remainder = <ContainingFieldType::ResultMut as PluckMut<
'a,
Nested<PluckedOuter, PluckedInner>,
Index,
>>::Remainder;
}
unsafe impl<
'a,
ContainingPart,
PluckedOuter,
PluckedInner,
Reference,
NestedPartIndex,
Index,
OuterFieldType,
ContainingFieldType,
> PluckConst<'a, Nested<PluckedOuter, PluckedInner>, IndexSplit<NestedPartIndex, Index>>
for Mut<ContainingPart, Reference>
where
PluckedOuter: Part<PartType = Field<OuterFieldType>>,
PluckedInner: Part,
ContainingPart: Part<PartType = Field<ContainingFieldType>>,
ContainingFieldType: SplitIntoParts<'a, ContainingPart, Reference>,
ContainingFieldType: ?Sized,
ContainingFieldType::ResultMut: PluckConst<'a, Nested<PluckedOuter, PluckedInner>, Index>,
OuterFieldType: ?Sized,
OuterFieldType: HasPart<PluckedInner>,
OuterFieldType: PartialRefTarget<RawTarget = OuterFieldType>,
Reference: PartialRef<'a>,
Reference::Target: HasPart<ContainingPart>,
ContainingPart: ContainsNestedPart<PluckedOuter, NestedPartIndex>,
{
type Remainder = <ContainingFieldType::ResultMut as PluckConst<
'a,
Nested<PluckedOuter, PluckedInner>,
Index,
>>::Remainder;
}
unsafe impl<
'a,
ContainingPart,
PluckedOuter,
PluckedInner,
Reference,
NestedPartIndex,
Index,
OuterFieldType,
ContainingFieldType,
> PluckConst<'a, Nested<PluckedOuter, PluckedInner>, IndexSplit<NestedPartIndex, Index>>
for Const<ContainingPart, Reference>
where
PluckedOuter: Part<PartType = Field<OuterFieldType>>,
PluckedInner: Part,
ContainingPart: Part<PartType = Field<ContainingFieldType>>,
ContainingFieldType: SplitIntoParts<'a, ContainingPart, Reference>,
ContainingFieldType: ?Sized,
ContainingFieldType::ResultMut: PluckConst<'a, Nested<PluckedOuter, PluckedInner>, Index>,
OuterFieldType: ?Sized,
OuterFieldType: HasPart<PluckedInner>,
OuterFieldType: PartialRefTarget<RawTarget = OuterFieldType>,
Reference: PartialRef<'a>,
Reference::Target: HasPart<ContainingPart>,
ContainingPart: ContainsNestedPart<PluckedOuter, NestedPartIndex>,
{
type Remainder = Const<ContainingPart, Reference>;
}
pub struct SubsetIndexEnd;
pub struct SubsetIndexCons<PartIndex, TailIndex>(PartIndex, TailIndex);
pub unsafe trait HasSubset<'a, Reference, SubsetIndex>: PartialRef<'a> {
type Remainder: PartialRef<'a, Target = Self::Target>;
}
unsafe impl<'a, Reference> HasSubset<'a, Ref<'a, Reference::Target>, SubsetIndexEnd> for Reference
where
Reference: PartialRef<'a>,
{
type Remainder = Reference;
}
unsafe impl<'a, SubsetPart, Reference, PluckedRef, PartIndex, TailIndex>
HasSubset<'a, Const<SubsetPart, Reference>, SubsetIndexCons<PartIndex, TailIndex>>
for PluckedRef
where
PluckedRef: PluckConst<'a, SubsetPart, PartIndex>,
<PluckedRef as PluckConst<'a, SubsetPart, PartIndex>>::Remainder:
HasSubset<'a, Reference, TailIndex>,
Reference: HasTarget,
{
type Remainder =
<<PluckedRef as PluckConst<'a, SubsetPart, PartIndex>>::Remainder as HasSubset<
'a,
Reference,
TailIndex,
>>::Remainder;
}
unsafe impl<'a, SubsetPart, Reference, PluckedRef, PartIndex, TailIndex>
HasSubset<'a, Mut<SubsetPart, Reference>, SubsetIndexCons<PartIndex, TailIndex>> for PluckedRef
where
PluckedRef: PluckMut<'a, SubsetPart, PartIndex>,
<PluckedRef as PluckMut<'a, SubsetPart, PartIndex>>::Remainder:
HasSubset<'a, Reference, TailIndex>,
Reference: HasTarget,
{
type Remainder =
<<PluckedRef as PluckMut<'a, SubsetPart, PartIndex>>::Remainder as HasSubset<
'a,
Reference,
TailIndex,
>>::Remainder;
}
pub trait ContainsNestedPart<NestedPart, Index>: Part {}
impl<NestedPart> ContainsNestedPart<NestedPart, IndexHere> for NestedPart where NestedPart: Part {}
impl<NestedPart, Outer, Inner, OuterFieldType, Index>
ContainsNestedPart<Nested<Outer, Inner>, IndexNext<Index>> for NestedPart
where
NestedPart: Part,
Inner: Part,
NestedPart: ContainsNestedPart<Outer, Index>,
Outer: Part<PartType = Field<OuterFieldType>>,
OuterFieldType: ?Sized,
OuterFieldType: HasPart<Inner>,
OuterFieldType: PartialRefTarget<RawTarget = OuterFieldType>,
{
}