dusk_wasmtime_runtime/gc/
i31.rs1use super::VMGcRef;
4
5#[derive(Clone, Copy, PartialEq, Eq, Hash)]
7pub struct I31(pub(super) u32);
8
9impl Default for I31 {
10 #[inline]
11 fn default() -> Self {
12 Self::wrapping_u32(0)
13 }
14}
15
16impl std::fmt::Debug for I31 {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 f.debug_struct("I31")
19 .field("as_u32", &self.get_u32())
20 .field("as_i32", &self.get_i32())
21 .finish()
22 }
23}
24
25impl I31 {
26 const DISCRIMINANT: u32 = VMGcRef::I31_REF_DISCRIMINANT;
27
28 #[inline]
32 pub fn new_u32(value: u32) -> Option<Self> {
33 if ((value << 1) >> 1) == value {
34 let i31 = Self::wrapping_u32(value);
35 debug_assert_eq!(i31.get_u32(), value);
36 Some(i31)
37 } else {
38 None
39 }
40 }
41
42 #[inline]
46 pub fn new_i32(value: i32) -> Option<Self> {
47 if ((value << 1) >> 1) == value {
48 let i31 = Self::wrapping_i32(value);
49 debug_assert_eq!(i31.get_i32(), value);
50 Some(i31)
51 } else {
52 None
53 }
54 }
55
56 #[inline]
61 pub fn wrapping_u32(value: u32) -> Self {
62 Self((value << 1) | Self::DISCRIMINANT)
63 }
64
65 #[inline]
70 #[allow(clippy::cast_sign_loss)]
71 pub fn wrapping_i32(value: i32) -> Self {
72 Self::wrapping_u32(value as u32)
73 }
74
75 #[inline]
77 pub fn get_u32(&self) -> u32 {
78 self.0 >> 1
79 }
80
81 #[inline]
83 pub fn get_i32(&self) -> i32 {
84 (self.0 as i32) >> 1
85 }
86}