abi_stable/nonexhaustive_enum/
alt_c_functions.rs

1use std::ptr;
2
3use crate::{
4    marker_type::ErasedObject,
5    nonexhaustive_enum::{
6        vtable::NonExhaustiveVtable_Ref, GetEnumInfo, NonExhaustive, SerializeEnum,
7    },
8    sabi_types::{RMut, RRef},
9    std_types::{RBoxError, RCmpOrdering, ROption, RResult, RSome},
10    traits::IntoReprC,
11};
12
13pub(crate) unsafe extern "C" fn drop_impl<E>(this: RMut<'_, ErasedObject>) {
14    extern_fn_panic_handling! {no_early_return; unsafe {
15        let this = this.transmute_into_mut::<E>();
16        ptr::drop_in_place(this);
17    }}
18}
19
20pub(crate) unsafe extern "C" fn clone_impl<E, F, I>(
21    this: RRef<'_, ErasedObject>,
22    vtable: NonExhaustiveVtable_Ref<E, F, I>,
23) -> NonExhaustive<E, F, I>
24where
25    E: GetEnumInfo,
26    E: Clone,
27{
28    extern_fn_panic_handling! {no_early_return; unsafe {
29        let this = this.transmute_into_ref::<E>();
30        NonExhaustive::with_vtable(this.clone(), vtable)
31    }}
32}
33
34pub(crate) unsafe extern "C" fn partial_eq_impl<E, F, I>(
35    this: RRef<'_, ErasedObject>,
36    other: RRef<'_, ErasedObject>,
37) -> bool
38where
39    E: GetEnumInfo + PartialEq,
40{
41    extern_fn_panic_handling! {no_early_return;
42        let this = unsafe { this.transmute_into_ref::<E>() };
43        let other = unsafe { other.transmute_into_ref::<NonExhaustive<E,F,I>>() };
44        match other.as_enum() {
45            Ok(other)=>this==other,
46            Err(_)=>false,
47        }
48    }
49}
50
51pub(crate) unsafe extern "C" fn cmp_ord<E, F, I>(
52    this: RRef<'_, ErasedObject>,
53    other: RRef<'_, ErasedObject>,
54) -> RCmpOrdering
55where
56    E: GetEnumInfo + Ord,
57{
58    extern_fn_panic_handling! {no_early_return;
59        let this = unsafe { this.transmute_into_ref::<E>() };
60        let other = unsafe { other.transmute_into_ref::<NonExhaustive<E,F,I>>() };
61
62        match other.as_enum() {
63            Ok(other)=>this.cmp(other).into_c(),
64            Err(_)=>RCmpOrdering::Less,
65        }
66    }
67}
68
69pub(crate) unsafe extern "C" fn partial_cmp_ord<E, F, I>(
70    this: RRef<'_, ErasedObject>,
71    other: RRef<'_, ErasedObject>,
72) -> ROption<RCmpOrdering>
73where
74    E: GetEnumInfo + PartialOrd,
75{
76    extern_fn_panic_handling! {no_early_return;
77        let this = unsafe { this.transmute_into_ref::<E>() };
78        let other = unsafe { other.transmute_into_ref::<NonExhaustive<E,F,I>>() };
79
80        match other.as_enum() {
81            Ok(other)=>this.partial_cmp(other).map(IntoReprC::into_c).into_c(),
82            Err(_)=>RSome(RCmpOrdering::Less),
83        }
84    }
85}
86
87pub(crate) unsafe extern "C" fn serialize_impl<E, I>(
88    this: RRef<'_, ErasedObject>,
89) -> RResult<<I as SerializeEnum<E>>::Proxy, RBoxError>
90where
91    I: SerializeEnum<E>,
92{
93    extern_fn_panic_handling! {no_early_return;
94        let this = unsafe { this.transmute_into_ref::<E>() };
95        I::serialize_enum(this).into()
96    }
97}