1use crate::{DowncastUnchecked, DynDynBase, DynDynTable, GetDynDynTable};
2use core::cmp::Ordering;
3use core::fmt::{self, Display, Pointer};
4use core::hash::{Hash, Hasher};
5use core::marker::{PhantomData, Unsize};
6use core::ops::CoerceUnsized;
7use core::ops::{Deref, DerefMut};
8use core::ptr::{self, Pointee};
9use stable_deref_trait::{CloneStableDeref, StableDeref};
10
11#[derive(Debug)]
17pub struct DynDynFat<B: ?Sized + DynDynBase, P> {
18 ptr: P,
19 table: DynDynTable,
20 _base: PhantomData<fn(B) -> B>,
21}
22
23impl<B: ?Sized + DynDynBase, P: GetDynDynTable<B>> DynDynFat<B, P> {
24 pub unsafe fn new_unchecked(ptr: P, table: DynDynTable) -> Self {
31 DynDynFat {
32 ptr,
33 table,
34 _base: PhantomData,
35 }
36 }
37
38 pub fn new(ptr: P) -> Self {
41 let table = ptr.get_dyn_dyn_table();
42
43 unsafe { Self::new_unchecked(ptr, table) }
45 }
46
47 pub fn get_dyn_dyn_table(ptr: &Self) -> DynDynTable {
49 ptr.table
50 }
51
52 pub fn unwrap(ptr: Self) -> P {
54 ptr.ptr
55 }
56}
57
58impl<B: ?Sized + DynDynBase, P: Deref> DynDynFat<B, P>
59where
60 P::Target: Unsize<B>,
61{
62 pub fn deref_fat(ptr: &Self) -> DynDynFat<B, &P::Target> {
64 DynDynFat {
65 ptr: ptr.ptr.deref(),
66 table: ptr.table,
67 _base: PhantomData,
68 }
69 }
70}
71
72impl<B: ?Sized + DynDynBase, P: DerefMut> DynDynFat<B, P>
73where
74 P::Target: Unsize<B>,
75{
76 pub fn deref_mut_fat(ptr: &mut Self) -> DynDynFat<B, &mut P::Target> {
78 DynDynFat {
79 ptr: ptr.ptr.deref_mut(),
80 table: ptr.table,
81 _base: PhantomData,
82 }
83 }
84}
85
86impl<B: ?Sized + DynDynBase, P: Clone> DynDynFat<B, P> {
87 pub unsafe fn clone_unchecked(ptr: &Self) -> Self {
94 DynDynFat {
95 ptr: ptr.ptr.clone(),
96 table: ptr.table,
97 _base: PhantomData,
98 }
99 }
100}
101
102unsafe impl<B: ?Sized + DynDynBase, P: GetDynDynTable<B>> GetDynDynTable<B> for DynDynFat<B, P> {
106 type DynTarget = P::DynTarget;
107
108 fn get_dyn_dyn_table(&self) -> DynDynTable {
109 self.table
110 }
111}
112
113impl<'a, B: ?Sized + DynDynBase, P: DowncastUnchecked<'a> + 'a> DowncastUnchecked<'a>
114 for DynDynFat<B, P>
115{
116 type DowncastResult<D: ?Sized + 'a> = <P as DowncastUnchecked<'a>>::DowncastResult<D>;
117
118 unsafe fn downcast_unchecked<D: ?Sized + Pointee>(
119 self,
120 metadata: <D as Pointee>::Metadata,
121 ) -> Self::DowncastResult<D> {
122 unsafe { self.ptr.downcast_unchecked(metadata) }
124 }
125}
126
127impl<B: ?Sized + DynDynBase, P: Deref> Deref for DynDynFat<B, P> {
128 type Target = P::Target;
129
130 fn deref(&self) -> &Self::Target {
131 self.ptr.deref()
132 }
133}
134
135unsafe impl<B: ?Sized + DynDynBase, P: StableDeref> StableDeref for DynDynFat<B, P> {}
137
138unsafe impl<B: ?Sized + DynDynBase, P: CloneStableDeref + GetDynDynTable<B>> CloneStableDeref
141 for DynDynFat<B, P>
142{
143}
144
145impl<B: ?Sized + DynDynBase, P: DerefMut> DerefMut for DynDynFat<B, P> {
146 fn deref_mut(&mut self) -> &mut Self::Target {
147 self.ptr.deref_mut()
148 }
149}
150
151impl<B: ?Sized + DynDynBase, P: Deref + Clone + GetDynDynTable<B>> Clone for DynDynFat<B, P> {
152 fn clone(&self) -> Self {
153 let ptr = self.ptr.clone();
154 let table = if ptr::eq(ptr.deref(), self.ptr.deref()) {
155 self.table
156 } else {
157 <P as GetDynDynTable<B>>::get_dyn_dyn_table(&ptr)
158 };
159
160 DynDynFat {
161 ptr,
162 table,
163 _base: PhantomData,
164 }
165 }
166}
167
168impl<B: ?Sized + DynDynBase, P: Deref + Copy + GetDynDynTable<B>> Copy for DynDynFat<B, P> where
169 P::Target: Unsize<B>
170{
171}
172
173impl<B: ?Sized + DynDynBase, P: GetDynDynTable<B> + Default> Default for DynDynFat<B, P> {
174 fn default() -> Self {
175 DynDynFat::new(Default::default())
176 }
177}
178
179impl<B: ?Sized + DynDynBase, P: GetDynDynTable<B>> From<P> for DynDynFat<B, P> {
180 fn from(ptr: P) -> Self {
181 DynDynFat::new(ptr)
182 }
183}
184
185impl<B: ?Sized + DynDynBase, P: Deref> AsRef<P> for DynDynFat<B, P> {
186 fn as_ref(&self) -> &P {
187 &self.ptr
188 }
189}
190
191impl<B1: ?Sized + DynDynBase, B2: ?Sized + DynDynBase, P1: Deref, P2: Deref>
192 PartialEq<DynDynFat<B2, P2>> for DynDynFat<B1, P1>
193where
194 P1::Target: Unsize<B1> + PartialEq<P2::Target>,
195 P2::Target: Unsize<B2>,
196{
197 fn eq(&self, other: &DynDynFat<B2, P2>) -> bool {
198 PartialEq::eq(&*self.ptr, &*other.ptr)
199 }
200}
201
202impl<B: ?Sized + DynDynBase, P: Deref> Eq for DynDynFat<B, P> where P::Target: Unsize<B> + Eq {}
203
204impl<B: ?Sized + DynDynBase, P: Deref> Hash for DynDynFat<B, P>
205where
206 P::Target: Unsize<B> + Hash,
207{
208 fn hash<H: Hasher>(&self, state: &mut H) {
209 Hash::hash(&*self.ptr, state)
210 }
211}
212
213impl<B1: ?Sized + DynDynBase, B2: ?Sized + DynDynBase, P1: Deref, P2: Deref>
214 PartialOrd<DynDynFat<B2, P2>> for DynDynFat<B1, P1>
215where
216 P1::Target: Unsize<B1> + PartialOrd<P2::Target>,
217 P2::Target: Unsize<B2>,
218{
219 fn partial_cmp(&self, other: &DynDynFat<B2, P2>) -> Option<Ordering> {
220 PartialOrd::partial_cmp(&*self.ptr, &*other.ptr)
221 }
222}
223
224impl<B: ?Sized + DynDynBase, P: Deref> Ord for DynDynFat<B, P>
225where
226 P::Target: Unsize<B> + Ord,
227{
228 fn cmp(&self, other: &Self) -> Ordering {
229 Ord::cmp(&*self.ptr, &*other.ptr)
230 }
231}
232
233impl<B: ?Sized + DynDynBase, P1: Deref + CoerceUnsized<P2>, P2: Deref>
234 CoerceUnsized<DynDynFat<B, P2>> for DynDynFat<B, P1>
235where
236 P1::Target: Unsize<B>,
237 P2::Target: Unsize<B>,
238{
239}
240
241impl<B: ?Sized + DynDynBase, P: Display> Display for DynDynFat<B, P> {
242 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
243 write!(f, "{}", self.ptr)
244 }
245}
246
247impl<B: ?Sized + DynDynBase, P: Pointer> Pointer for DynDynFat<B, P> {
248 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
249 write!(f, "{:p}", self.ptr)
250 }
251}