linera_wit_bindgen_guest_rust/
lib.rs1use std::fmt;
2use std::marker;
3use std::mem;
4use std::ops::Deref;
5
6#[cfg(feature = "macros")]
7pub use wit_bindgen_guest_rust_macro::{export, import};
8
9#[doc(hidden)]
11pub use bitflags;
12
13pub struct Handle<T: HandleType> {
21 val: i32,
22 _marker: marker::PhantomData<T>,
23}
24
25impl<T: HandleType> Handle<T> {
26 pub fn new(val: T) -> Handle<T>
34 where
35 T: LocalHandle,
36 {
37 unsafe { Handle::from_raw(T::new(Box::into_raw(Box::new(val)) as i32)) }
38 }
39
40 pub fn into_raw(handle: Handle<T>) -> i32 {
46 let ret = handle.val;
47 mem::forget(handle);
48 ret
49 }
50
51 pub fn as_raw(handle: &Handle<T>) -> i32 {
56 handle.val
57 }
58
59 pub unsafe fn from_raw(val: i32) -> Handle<T> {
64 Handle {
65 val,
66 _marker: marker::PhantomData,
67 }
68 }
69}
70
71impl<T: LocalHandle> Deref for Handle<T> {
72 type Target = T;
73
74 fn deref(&self) -> &T {
75 unsafe { &*(T::get(self.val) as *const T) }
76 }
77}
78
79impl<T: LocalHandle> From<T> for Handle<T> {
80 fn from(val: T) -> Handle<T> {
81 Handle::new(val)
82 }
83}
84
85impl<T: HandleType> Clone for Handle<T> {
86 fn clone(&self) -> Self {
87 unsafe { Handle::from_raw(T::clone(self.val)) }
88 }
89}
90
91impl<T: HandleType> fmt::Debug for Handle<T> {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 f.debug_struct("Handle").field("val", &self.val).finish()
94 }
95}
96
97impl<T: HandleType> Drop for Handle<T> {
98 fn drop(&mut self) {
99 T::drop(self.val);
100 }
101}
102
103pub unsafe trait HandleType {
108 #[doc(hidden)]
109 fn clone(val: i32) -> i32;
110 #[doc(hidden)]
111 fn drop(val: i32);
112}
113
114pub unsafe trait LocalHandle: HandleType {
118 #[doc(hidden)]
119 fn new(val: i32) -> i32;
120 #[doc(hidden)]
121 fn get(val: i32) -> i32;
122}
123
124#[doc(hidden)]
125pub mod rt {
126 use std::alloc::{self, Layout};
127
128 #[no_mangle]
129 unsafe extern "C" fn cabi_realloc(
130 old_ptr: *mut u8,
131 old_len: usize,
132 align: usize,
133 new_len: usize,
134 ) -> *mut u8 {
135 let layout;
136 let ptr = if old_len == 0 {
137 if new_len == 0 {
138 return align as *mut u8;
139 }
140 layout = Layout::from_size_align_unchecked(new_len, align);
141 alloc::alloc(layout)
142 } else {
143 layout = Layout::from_size_align_unchecked(old_len, align);
144 alloc::realloc(old_ptr, layout, new_len)
145 };
146 if ptr.is_null() {
147 alloc::handle_alloc_error(layout);
148 }
149 return ptr;
150 }
151
152 #[no_mangle]
153 pub unsafe extern "C" fn canonical_abi_free(ptr: *mut u8, len: usize, align: usize) {
154 if len == 0 {
155 return;
156 }
157 let layout = Layout::from_size_align_unchecked(len, align);
158 alloc::dealloc(ptr, layout);
159 }
160
161 macro_rules! as_traits {
162 ($(($trait_:ident $func:ident $ty:ident <=> $($tys:ident)*))*) => ($(
163 pub fn $func<T: $trait_>(t: T) -> $ty {
164 t.$func()
165 }
166
167 pub trait $trait_ {
168 fn $func(self) -> $ty;
169 }
170
171 impl<'a, T: Copy + $trait_> $trait_ for &'a T {
172 fn $func(self) -> $ty{
173 (*self).$func()
174 }
175 }
176
177 $(
178 impl $trait_ for $tys {
179 #[inline]
180 fn $func(self) -> $ty {
181 self as $ty
182 }
183 }
184 )*
185
186 )*)
187 }
188
189 as_traits! {
190 (AsI64 as_i64 i64 <=> i64 u64)
191 (AsI32 as_i32 i32 <=> i32 u32 i16 u16 i8 u8 char usize)
192 (AsF32 as_f32 f32 <=> f32)
193 (AsF64 as_f64 f64 <=> f64)
194 }
195}