struct_split/
lib.rs

1use std::fmt::Debug;
2use std::marker::PhantomData;
3pub use struct_split_macro::*;
4
5// ==============
6// === Traits ===
7// ==============
8
9pub mod traits {
10    pub use super::Access as _;
11    pub use super::Acquire as _;
12    pub use super::Split as _;
13    pub use super::SplitHelper as _;
14    pub use super::RefCast as _;
15    pub use super::AsRefs as _;
16    pub use super::AsRefsHelper as _;
17}
18
19
20// ===============
21// === Labeled ===
22// ===============
23
24#[repr(transparent)]
25pub struct Labeled<L, T> {
26    label: PhantomData<L>,
27    data: T,
28}
29
30
31// ===================
32// === Access Flag ===
33// ===================
34
35#[derive(Debug)]
36pub struct None;
37
38#[derive(Debug)]
39pub struct Ref;
40
41#[derive(Debug)]
42pub struct RefMut;
43
44
45// =========================
46// === No Access Wrapper ===
47// =========================
48
49#[repr(transparent)]
50#[derive(Debug)]
51pub struct NoAccess<T>(*mut T);
52
53
54// ===============
55// === RefCast ===
56// ===============
57
58pub trait RefCast<'t, T> {
59    fn ref_cast(&'t mut self) -> T;
60}
61
62impl<'t, T> RefCast<'t, &'t T> for T {
63    #[inline(always)]
64    fn ref_cast(&'t mut self) -> &'t T { self }
65}
66
67impl<'t, T> RefCast<'t, &'t mut T> for T {
68    #[inline(always)]
69    fn ref_cast(&'t mut self) -> &'t mut T { self }
70}
71
72impl<'t, T> RefCast<'t, NoAccess<T>> for T {
73    #[inline(always)]
74    fn ref_cast(&'t mut self) -> NoAccess<T> { NoAccess(self) }
75}
76
77
78// ==============
79// === Access ===
80// ==============
81
82pub trait Access            { type Value<'t, T: 't + Debug>: Debug; }
83impl      Access for Ref    { type Value<'t, T: 't + Debug> = &'t T; }
84impl      Access for RefMut { type Value<'t, T: 't + Debug> = &'t mut T; }
85impl      Access for None   { type Value<'t, T: 't + Debug> = NoAccess<T>; }
86impl<L, S> Access for Labeled<L, S>
87where S: Access {
88    type Value<'t, T: 't + Debug> = S::Value<'t, T>;
89}
90
91pub type Value<'t, L, T> = <L as Access>::Value<'t, T>;
92
93
94// ===============
95// === Acquire ===
96// ===============
97
98pub trait       Acquire<Target: Access>    { type Rest: Access; }
99impl<T: Access> Acquire<None>   for T      { type Rest = T; }
100impl            Acquire<RefMut> for RefMut { type Rest = None; }
101impl            Acquire<Ref>    for RefMut { type Rest = Ref; }
102impl            Acquire<Ref>    for Ref    { type Rest = Ref; }
103
104pub type Acquired<This, Target> = <This as Acquire<Target>>::Rest;
105
106
107// =============
108// === Split ===
109// =============
110
111pub trait Split<Target> {
112    type Rest;
113
114    #[inline(always)]
115    fn fit_impl(&mut self) -> &mut Target {
116        unsafe { &mut *(self as *mut _ as *mut _) }
117    }
118
119    #[inline(always)]
120    fn fit_rest_impl(&mut self) -> &mut Self::Rest {
121        unsafe { &mut *(self as *mut _ as *mut _) }
122    }
123
124    #[inline(always)]
125    fn split_impl(&mut self) -> (&mut Target, &mut Self::Rest) {
126        let a = unsafe { &mut *(self as *mut _ as *mut _) };
127        let b = unsafe { &mut *(self as *mut _ as *mut _) };
128        (a, b)
129    }
130}
131
132impl<T> SplitHelper for T {}
133pub trait SplitHelper {
134    #[inline(always)]
135    fn fit<Target>(&mut self) -> &mut Target
136    where Self: Split<Target> { self.fit_impl() }
137
138    #[inline(always)]
139    fn fit_rest<Target>(&mut self) -> &mut Self::Rest
140    where Self: Split<Target> { self.fit_rest_impl() }
141
142    #[inline(always)]
143    fn split<Target>(&mut self) -> (&mut Target, &mut Self::Rest)
144    where Self: Split<Target> { self.split_impl() }
145}
146
147
148// ==============
149// === AsRefs ===
150// ==============
151
152pub trait AsRefs<'t, T> {
153    fn as_refs_impl(&'t mut self) -> T;
154}
155
156impl<'t, T> AsRefsHelper<'t> for T {}
157pub trait AsRefsHelper<'t> {
158    #[inline(always)]
159    fn as_refs<T>(&'t mut self) -> T
160    where Self: AsRefs<'t, T> { self.as_refs_impl() }
161}