abi_stable/sabi_trait/
vtable.rs

1use super::*;
2
3use crate::{
4    erased_types::{FormattingMode, InterfaceType, MakeRequiredTraits},
5    marker_type::NonOwningPhantom,
6    std_types::{RResult, RString, UTypeId},
7    type_level::{
8        downcasting::GetUTID,
9        impl_enum::{Implemented, Unimplemented},
10        trait_marker,
11    },
12};
13
14use std::marker::PhantomData;
15
16//////////////////////////////////////////////////////////////////////////////
17
18#[doc(hidden)]
19pub struct Private<A: ?Sized, B: ?Sized, C: ?Sized, D: ?Sized, E: ?Sized>(
20    PhantomData<(
21        PhantomData<A>,
22        PhantomData<B>,
23        PhantomData<C>,
24        PhantomData<D>,
25        PhantomData<E>,
26    )>,
27);
28
29/// Gets an `RObjectVtable_Ref<_Self,ErasedPtr,TO>`(the vtable for RObject itself),
30/// which is stored as the first field of all generated trait object vtables.
31///
32/// This trait cannot be implemented outside of `abi_stable`,
33/// it can only be used.
34pub trait GetRObjectVTable<IA, _Self, ErasedPtr, OrigPtr>: Sized + InterfaceType {
35    // Using privacy to make it impossible to implement this trait outside this module.
36    #[doc(hidden)]
37    const __HIDDEN_10341423423AB__: Private<Self, IA, _Self, ErasedPtr, OrigPtr>;
38
39    const ROBJECT_VTABLE: RObjectVtable_Ref<_Self, ErasedPtr, Self>;
40}
41
42impl<IA, _Self, ErasedPtr, OrigPtr, I> GetRObjectVTable<IA, _Self, ErasedPtr, OrigPtr> for I
43where
44    I: AreTraitsImpld<IA, _Self, ErasedPtr, OrigPtr> + InterfaceType,
45{
46    const __HIDDEN_10341423423AB__: Private<Self, IA, _Self, ErasedPtr, OrigPtr> =
47        Private(std::marker::PhantomData);
48
49    const ROBJECT_VTABLE: RObjectVtable_Ref<_Self, ErasedPtr, Self> =
50        { GetRObjectVTableHelper::<IA, _Self, ErasedPtr, OrigPtr, I>::TMP_VTABLE };
51}
52
53//////////////////////////////////////////////////////////////////////////////
54
55#[doc(hidden)]
56pub trait AreTraitsImpld<IA, _Self, ErasedPtr, OrigPtr>: Sized {
57    const VTABLE_VAL: RObjectVtable<_Self, ErasedPtr, Self>;
58}
59
60impl<IA, _Self, ErasedPtr, OrigPtr, I> AreTraitsImpld<IA, _Self, ErasedPtr, OrigPtr> for I
61where
62    I: InterfaceType,
63    I::Sync: RequiresSync<_Self, ErasedPtr, OrigPtr>,
64    I::Send: RequiresSend<_Self, ErasedPtr, OrigPtr>,
65    I::Clone: InitCloneField<_Self, ErasedPtr, OrigPtr>,
66    I::Debug: InitDebugField<_Self, ErasedPtr, OrigPtr>,
67    I::Display: InitDisplayField<_Self, ErasedPtr, OrigPtr>,
68    IA: GetUTID<_Self>,
69{
70    const VTABLE_VAL: RObjectVtable<_Self, ErasedPtr, I> = RObjectVtable {
71        _sabi_tys: NonOwningPhantom::NEW,
72        _sabi_type_id: <IA as GetUTID<_Self>>::UID,
73        _sabi_drop: c_functions::drop_pointer_impl::<OrigPtr, ErasedPtr>,
74        _sabi_clone: <I::Clone as InitCloneField<_Self, ErasedPtr, OrigPtr>>::VALUE,
75        _sabi_debug: <I::Debug as InitDebugField<_Self, ErasedPtr, OrigPtr>>::VALUE,
76        _sabi_display: <I::Display as InitDisplayField<_Self, ErasedPtr, OrigPtr>>::VALUE,
77    };
78}
79
80// A dummy type used to get around a compiler limitation WRT associated constants in traits.
81#[doc(hidden)]
82struct GetRObjectVTableHelper<IA, _Self, ErasedPtr, OrigPtr, I>(IA, _Self, ErasedPtr, OrigPtr, I);
83
84impl<IA, _Self, ErasedPtr, OrigPtr, I> GetRObjectVTableHelper<IA, _Self, ErasedPtr, OrigPtr, I>
85where
86    I: AreTraitsImpld<IA, _Self, ErasedPtr, OrigPtr>,
87{
88    staticref! {
89        const TMP_WM: WithMetadata<RObjectVtable<_Self,ErasedPtr,I>> =
90            WithMetadata::new(I::VTABLE_VAL);
91    }
92
93    const TMP_VTABLE: RObjectVtable_Ref<_Self, ErasedPtr, I> =
94        RObjectVtable_Ref(Self::TMP_WM.as_prefix());
95}
96
97/// The vtable for RObject,which all  `#[trait_object]` derived trait objects contain.
98#[repr(C)]
99#[derive(StableAbi)]
100#[sabi(kind(Prefix))]
101#[sabi(missing_field(default))]
102pub struct RObjectVtable<_Self, ErasedPtr, I> {
103    pub _sabi_tys: NonOwningPhantom<(_Self, ErasedPtr, I)>,
104
105    pub _sabi_type_id: extern "C" fn() -> MaybeCmp<UTypeId>,
106
107    pub _sabi_drop: unsafe extern "C" fn(this: RMut<'_, ErasedPtr>),
108    pub _sabi_clone: Option<unsafe extern "C" fn(this: RRef<'_, ErasedPtr>) -> ErasedPtr>,
109    pub _sabi_debug: Option<
110        unsafe extern "C" fn(
111            RRef<'_, ErasedObject>,
112            FormattingMode,
113            &mut RString,
114        ) -> RResult<(), ()>,
115    >,
116    #[sabi(last_prefix_field)]
117    pub _sabi_display: Option<
118        unsafe extern "C" fn(
119            RRef<'_, ErasedObject>,
120            FormattingMode,
121            &mut RString,
122        ) -> RResult<(), ()>,
123    >,
124}
125
126/// The common prefix of all `#[trait_object]` derived vtables,
127/// with `RObjectVtable_Ref` as its first field.
128#[repr(C)]
129#[derive(StableAbi)]
130#[sabi(
131    bound(I: InterfaceType),
132    extra_checks = <I as MakeRequiredTraits>::MAKE,
133    kind(Prefix)
134)]
135pub(super) struct BaseVtable<_Self, ErasedPtr, I> {
136    pub _sabi_tys: NonOwningPhantom<(_Self, ErasedPtr, I)>,
137
138    #[sabi(last_prefix_field)]
139    pub _sabi_vtable: RObjectVtable_Ref<_Self, ErasedPtr, I>,
140}
141
142use self::trait_bounds::*;
143pub mod trait_bounds {
144    use super::*;
145
146    macro_rules! declare_conditional_marker {
147        (
148            type $selector:ident;
149            trait $trait_name:ident[$self_:ident,$ErasedPtr:ident,$OrigPtr:ident]
150            where [ $($where_preds:tt)* ]
151        ) => (
152            pub trait $trait_name<$self_,$ErasedPtr,$OrigPtr>{}
153
154            impl<$self_,$ErasedPtr,$OrigPtr> $trait_name<$self_,$ErasedPtr,$OrigPtr>
155            for Unimplemented<trait_marker::$selector>
156            {}
157
158            impl<$self_,$ErasedPtr,$OrigPtr> $trait_name<$self_,ErasedPtr,$OrigPtr>
159            for Implemented<trait_marker::$selector>
160            where
161                $($where_preds)*
162            {}
163        )
164    }
165
166    macro_rules! declare_field_initalizer {
167        (
168            type $selector:ident;
169            trait $trait_name:ident[$self_:ident,$ErasedPtr:ident,$OrigPtr:ident]
170            where [ $($where_preds:tt)* ]
171            type=$field_ty:ty,
172            value=$field_value:expr,
173        ) => (
174            pub trait $trait_name<$self_,$ErasedPtr,$OrigPtr>{
175                const VALUE:Option<$field_ty>;
176            }
177
178            impl<$self_,$ErasedPtr,$OrigPtr> $trait_name<$self_,$ErasedPtr,$OrigPtr>
179            for Unimplemented<trait_marker::$selector>
180            {
181                const VALUE:Option<$field_ty>=None;
182            }
183
184            impl<$self_,$ErasedPtr,$OrigPtr> $trait_name<$self_,ErasedPtr,$OrigPtr>
185            for Implemented<trait_marker::$selector>
186            where
187                $($where_preds)*
188            {
189                const VALUE:Option<$field_ty>=Some($field_value);
190            }
191        )
192    }
193
194    declare_conditional_marker! {
195        type Send;
196        trait RequiresSend[_Self,ErasedPtr,OrigPtr]
197        where [ _Self:Send,OrigPtr:Send ]
198    }
199
200    declare_conditional_marker! {
201        type Sync;
202        trait RequiresSync[_Self,ErasedPtr,OrigPtr]
203        where [ _Self:Sync,OrigPtr:Sync ]
204    }
205
206    declare_field_initalizer! {
207        type Clone;
208        trait InitCloneField[_Self,ErasedPtr,OrigPtr]
209        where [ OrigPtr:Clone ]
210        type=unsafe extern "C" fn(this:RRef<'_, ErasedPtr>)->ErasedPtr,
211        value=c_functions::clone_pointer_impl::<OrigPtr,ErasedPtr>,
212    }
213    declare_field_initalizer! {
214        type Debug;
215        trait InitDebugField[_Self,ErasedPtr,OrigPtr]
216        where [ _Self:Debug ]
217        type=unsafe extern "C" fn(RRef<'_, ErasedObject>,FormattingMode,&mut RString)->RResult<(),()>,
218        value=c_functions::debug_impl::<_Self>,
219    }
220    declare_field_initalizer! {
221        type Display;
222        trait InitDisplayField[_Self,ErasedPtr,OrigPtr]
223        where [ _Self:Display ]
224        type=unsafe extern "C" fn(RRef<'_, ErasedObject>,FormattingMode,&mut RString)->RResult<(),()>,
225        value=c_functions::display_impl::<_Self>,
226    }
227}