ark_api_ffi/
pod_helpers.rs1use core::ops::Deref;
18use core::ops::DerefMut;
19
20use bytemuck::AnyBitPattern;
21use bytemuck::Pod;
22use bytemuck::Zeroable;
23
24#[repr(C, align(16))]
33#[derive(Copy, Clone, Pod, Zeroable, Default, Debug)]
34pub struct Align16U128(pub u128);
35
36impl Deref for Align16U128 {
37 type Target = u128;
38 fn deref(&self) -> &Self::Target {
39 &self.0
40 }
41}
42
43impl DerefMut for Align16U128 {
44 fn deref_mut(&mut self) -> &mut Self::Target {
45 &mut self.0
46 }
47}
48
49impl AsRef<u128> for Align16U128 {
50 fn as_ref(&self) -> &u128 {
51 &self.0
52 }
53}
54
55impl AsMut<u128> for Align16U128 {
56 fn as_mut(&mut self) -> &mut u128 {
57 &mut self.0
58 }
59}
60
61impl From<u128> for Align16U128 {
62 fn from(value: u128) -> Self {
63 Self(value)
64 }
65}
66
67impl From<Align16U128> for u128 {
68 fn from(value: Align16U128) -> Self {
69 value.0
70 }
71}
72
73impl core::fmt::Display for Align16U128 {
74 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
75 write!(f, "{}", self.0)
76 }
77}
78
79#[repr(C, align(16))]
88#[derive(Copy, Clone, Pod, Zeroable, Default, Debug)]
89pub struct Align16I128(pub i128);
90
91impl Deref for Align16I128 {
92 type Target = i128;
93 fn deref(&self) -> &Self::Target {
94 &self.0
95 }
96}
97
98impl DerefMut for Align16I128 {
99 fn deref_mut(&mut self) -> &mut Self::Target {
100 &mut self.0
101 }
102}
103
104impl AsRef<i128> for Align16I128 {
105 fn as_ref(&self) -> &i128 {
106 &self.0
107 }
108}
109
110impl AsMut<i128> for Align16I128 {
111 fn as_mut(&mut self) -> &mut i128 {
112 &mut self.0
113 }
114}
115
116impl From<i128> for Align16I128 {
117 fn from(value: i128) -> Self {
118 Self(value)
119 }
120}
121
122impl From<Align16I128> for i128 {
123 fn from(value: Align16I128) -> Self {
124 value.0
125 }
126}
127
128impl core::fmt::Display for Align16I128 {
129 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
130 write!(f, "{}", self.0)
131 }
132}
133
134#[repr(C)]
143#[derive(Copy, Clone, Eq, PartialEq, Pod, Zeroable)]
144pub struct PodBool(u8);
145
146impl core::fmt::Debug for PodBool {
147 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
148 if let Ok(b) = self.try_as_bool() {
149 write!(f, "PodBool({})", b)
150 } else {
151 write!(f, "PodBool(InvalidValue({}))", self.0)
152 }
153 }
154}
155
156impl From<bool> for PodBool {
157 fn from(v: bool) -> Self {
158 Self(u8::from(v))
159 }
160}
161
162pub struct InvalidPodBool {}
164
165impl PodBool {
166 pub fn as_bool(&self) -> bool {
167 match self.0 {
168 0 => false,
169 1 => true,
170 #[allow(clippy::panic)]
171 _ => panic!("invalid value in PodBool"),
172 }
173 }
174
175 pub fn try_as_bool(&self) -> Result<bool, InvalidPodBool> {
176 match self.0 {
177 0 => Ok(false),
178 1 => Ok(true),
179 _ => Err(InvalidPodBool {}),
180 }
181 }
182}
183
184#[derive(Copy, Clone)]
194#[repr(C)]
195pub struct TransparentPad<T, const PAD: usize>(pub T, [u8; PAD]);
196
197#[allow(unsafe_code)]
198unsafe impl<T: Zeroable, const PAD: usize> Zeroable for TransparentPad<T, PAD> {}
200
201#[allow(unsafe_code)]
202unsafe impl<T: AnyBitPattern, const PAD: usize> AnyBitPattern for TransparentPad<T, PAD> {}
204
205#[doc(hidden)] #[macro_export]
207macro_rules! impl_checked_bit_pattern_for_transparent_pad {
208 ($inner:ident) => {
209 #[allow(unsafe_code)]
210 unsafe impl<const PAD: usize> bytemuck::CheckedBitPattern
213 for $crate::TransparentPad<$inner, PAD>
214 {
215 type Bits = $crate::TransparentPad<<$inner as bytemuck::CheckedBitPattern>::Bits, PAD>;
216
217 fn is_valid_bit_pattern(bits: &Self::Bits) -> bool {
218 <$inner as bytemuck::CheckedBitPattern>::is_valid_bit_pattern(&bits.0)
219 }
220 }
221 };
222}
223
224impl<T, const PAD: usize> TransparentPad<T, PAD> {
225 pub fn new(inner: T) -> Self {
226 Self(inner, [0u8; PAD])
227 }
228}
229
230impl<T, const PAD: usize> AsRef<T> for TransparentPad<T, PAD> {
231 fn as_ref(&self) -> &T {
232 &self.0
233 }
234}
235
236impl<T, const PAD: usize> AsMut<T> for TransparentPad<T, PAD> {
237 fn as_mut(&mut self) -> &mut T {
238 &mut self.0
239 }
240}
241
242impl<T, const PAD: usize> core::ops::Deref for TransparentPad<T, PAD> {
243 type Target = T;
244
245 fn deref(&self) -> &Self::Target {
246 &self.0
247 }
248}
249
250impl<T, const PAD: usize> core::ops::DerefMut for TransparentPad<T, PAD> {
251 fn deref_mut(&mut self) -> &mut Self::Target {
252 &mut self.0
253 }
254}