abi_stable/sabi_types/constructor.rs
1use std::{
2 cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
3 fmt::{self, Debug, Display},
4};
5
6/// Newtype wrapper to pass function pointers to `const fn`.
7///
8/// A workaround for it not being possible to get a function pointer within a `const fn`,
9/// since it's possible to pass structs that happen to have function pointer fields.
10///
11/// Every impl of this type delegates the impl to the return value of the wrapped function
12/// (which it calls every time),don't use those impls if the function is likely expensive.
13///
14/// # Example
15///
16/// ```
17/// use abi_stable::{
18/// sabi_types::Constructor,
19/// std_types::{RNone, ROption, RSome},
20/// };
21///
22/// extern "C" fn returns_100() -> ROption<u32> {
23/// RSome(100)
24/// }
25///
26/// extern "C" fn returns_100b() -> ROption<u32> {
27/// RSome(100)
28/// }
29///
30/// extern "C" fn returns_200() -> ROption<u32> {
31/// RSome(200)
32/// }
33///
34/// extern "C" fn returns_none() -> ROption<u32> {
35/// RNone
36/// }
37///
38/// const A: Constructor<ROption<u32>> = Constructor(returns_100);
39/// const B: Constructor<ROption<u32>> = Constructor(returns_100b);
40/// const C: Constructor<ROption<u32>> = Constructor(returns_200);
41/// const D: Constructor<ROption<u32>> = Constructor(returns_none);
42///
43/// assert_eq!(A, A);
44/// assert_eq!(B, B);
45/// assert_eq!(C, C);
46/// assert_eq!(D, D);
47///
48/// assert_eq!(A, B);
49///
50/// assert_ne!(A, C);
51/// assert_ne!(A, D);
52/// assert_ne!(B, C);
53/// assert_ne!(C, D);
54///
55/// ```
56///
57#[repr(transparent)]
58#[derive(StableAbi)]
59// #[sabi(debug_print)]
60pub struct Constructor<T>(pub extern "C" fn() -> T);
61
62impl<T> Copy for Constructor<T> {}
63
64impl<T> Clone for Constructor<T> {
65 fn clone(&self) -> Self {
66 *self
67 }
68}
69
70impl<T> Debug for Constructor<T>
71where
72 T: Debug,
73{
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 Debug::fmt(&self.get(), f)
76 }
77}
78
79impl<T> Display for Constructor<T>
80where
81 T: Display,
82{
83 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84 Display::fmt(&self.get(), f)
85 }
86}
87
88impl<T> Constructor<T> {
89 /// Constructs a `T` by calling the wrapped function.
90 pub fn get(self) -> T {
91 (self.0)()
92 }
93
94 pub(crate) const fn wrap_slice(slice: &[extern "C" fn() -> T]) -> &[Constructor<T>] {
95 unsafe { &*(slice as *const [extern "C" fn() -> T] as *const [Constructor<T>]) }
96 }
97 pub(crate) const fn unwrap_slice(slice: &[Constructor<T>]) -> &[extern "C" fn() -> T] {
98 unsafe { &*(slice as *const [Constructor<T>] as *const [extern "C" fn() -> T]) }
99 }
100}
101
102impl<T> Eq for Constructor<T> where T: Eq {}
103
104impl<T> PartialEq for Constructor<T>
105where
106 T: PartialEq,
107{
108 fn eq(&self, other: &Self) -> bool {
109 self.get() == other.get()
110 }
111}
112
113impl<T> Ord for Constructor<T>
114where
115 T: Ord,
116{
117 fn cmp(&self, other: &Self) -> Ordering {
118 self.get().cmp(&other.get())
119 }
120}
121
122impl<T> PartialOrd for Constructor<T>
123where
124 T: PartialOrd,
125{
126 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
127 self.get().partial_cmp(&other.get())
128 }
129}
130
131////////////////////////////////////////////////////////////////////////////////
132
133/// Either the constructor for a value or the value itself
134#[repr(u8)]
135#[derive(StableAbi, Copy, Clone)]
136//#[sabi(debug_print)]
137pub enum ConstructorOrValue<T> {
138 /// This is an `extern "C" fn()->T` which is used to construct a value of type `T`
139 Constructor(Constructor<T>),
140 /// A value of type `T`
141 Value(T),
142}
143
144impl<T> ConstructorOrValue<T> {
145 /// Gets the wrapped value,computing it from its constructor if this
146 /// is the `Constructor` variant
147 pub fn get(&mut self) -> &T {
148 match self {
149 ConstructorOrValue::Value(v) => v,
150 &mut ConstructorOrValue::Constructor(func) => {
151 let v = (func.0)();
152 *self = ConstructorOrValue::Value(v);
153 match self {
154 ConstructorOrValue::Value(v) => v,
155 _ => unreachable!(),
156 }
157 }
158 }
159 }
160}