1use crate::{
2 WasmtimeStoreContextMut, handle_result, wasm_name_t, wasmtime_component_resource_type_t,
3 wasmtime_error_t,
4};
5use std::mem;
6use std::mem::{ManuallyDrop, MaybeUninit};
7use std::ptr;
8use std::slice;
9use wasmtime::component::{ResourceAny, ResourceDynamic, Val};
10
11crate::declare_vecs! {
12 (
13 name: wasmtime_component_vallist_t,
14 ty: wasmtime_component_val_t,
15 new: wasmtime_component_vallist_new,
16 empty: wasmtime_component_vallist_new_empty,
17 uninit: wasmtime_component_vallist_new_uninit,
18 copy: wasmtime_component_vallist_copy,
19 delete: wasmtime_component_vallist_delete,
20 )
21 (
22 name: wasmtime_component_valrecord_t,
23 ty: wasmtime_component_valrecord_entry_t,
24 new: wasmtime_component_valrecord_new,
25 empty: wasmtime_component_valrecord_new_empty,
26 uninit: wasmtime_component_valrecord_new_uninit,
27 copy: wasmtime_component_valrecord_copy,
28 delete: wasmtime_component_valrecord_delete,
29 )
30 (
31 name: wasmtime_component_valtuple_t,
32 ty: wasmtime_component_val_t,
33 new: wasmtime_component_valtuple_new,
34 empty: wasmtime_component_valtuple_new_empty,
35 uninit: wasmtime_component_valtuple_new_uninit,
36 copy: wasmtime_component_valtuple_copy,
37 delete: wasmtime_component_valtuple_delete,
38 )
39 (
40 name: wasmtime_component_valflags_t,
41 ty: wasm_name_t,
42 new: wasmtime_component_valflags_new,
43 empty: wasmtime_component_valflags_new_empty,
44 uninit: wasmtime_component_valflags_new_uninit,
45 copy: wasmtime_component_valflags_copy,
46 delete: wasmtime_component_valflags_delete,
47 )
48}
49
50impl From<&wasmtime_component_vallist_t> for Vec<Val> {
51 fn from(value: &wasmtime_component_vallist_t) -> Self {
52 value.as_slice().iter().map(Val::from).collect()
53 }
54}
55
56impl From<&[Val]> for wasmtime_component_vallist_t {
57 fn from(value: &[Val]) -> Self {
58 value
59 .iter()
60 .map(wasmtime_component_val_t::from)
61 .collect::<Vec<_>>()
62 .into()
63 }
64}
65
66#[derive(Clone)]
67#[repr(C)]
68pub struct wasmtime_component_valrecord_entry_t {
69 name: wasm_name_t,
70 val: wasmtime_component_val_t,
71}
72
73impl Default for wasmtime_component_valrecord_entry_t {
74 fn default() -> Self {
75 Self {
76 name: wasm_name_t::from_name(String::new()),
77 val: Default::default(),
78 }
79 }
80}
81
82impl From<&wasmtime_component_valrecord_entry_t> for (String, Val) {
83 fn from(value: &wasmtime_component_valrecord_entry_t) -> Self {
84 (
85 String::from_utf8(value.name.clone().take()).unwrap(),
86 Val::from(&value.val),
87 )
88 }
89}
90
91impl From<&(String, Val)> for wasmtime_component_valrecord_entry_t {
92 fn from((name, val): &(String, Val)) -> Self {
93 Self {
94 name: wasm_name_t::from_name(name.clone()),
95 val: wasmtime_component_val_t::from(val),
96 }
97 }
98}
99
100impl From<&wasmtime_component_valrecord_t> for Vec<(String, Val)> {
101 fn from(value: &wasmtime_component_valrecord_t) -> Self {
102 value.as_slice().iter().map(Into::into).collect()
103 }
104}
105
106impl From<&[(String, Val)]> for wasmtime_component_valrecord_t {
107 fn from(value: &[(String, Val)]) -> Self {
108 value
109 .iter()
110 .map(wasmtime_component_valrecord_entry_t::from)
111 .collect::<Vec<_>>()
112 .into()
113 }
114}
115
116impl From<&wasmtime_component_valtuple_t> for Vec<Val> {
117 fn from(value: &wasmtime_component_valtuple_t) -> Self {
118 value.as_slice().iter().map(Val::from).collect()
119 }
120}
121
122impl From<&[Val]> for wasmtime_component_valtuple_t {
123 fn from(value: &[Val]) -> Self {
124 value
125 .iter()
126 .map(wasmtime_component_val_t::from)
127 .collect::<Vec<_>>()
128 .into()
129 }
130}
131
132impl From<&wasmtime_component_valflags_t> for Vec<String> {
133 fn from(value: &wasmtime_component_valflags_t) -> Self {
134 value
135 .clone()
136 .take()
137 .into_iter()
138 .map(|mut x| String::from_utf8(x.take()))
139 .collect::<Result<Vec<_>, _>>()
140 .unwrap()
141 }
142}
143
144impl From<&[String]> for wasmtime_component_valflags_t {
145 fn from(value: &[String]) -> Self {
146 value
147 .iter()
148 .map(|x| wasm_name_t::from_name(x.clone()))
149 .collect::<Vec<_>>()
150 .into()
151 }
152}
153
154#[repr(C)]
155#[derive(Clone)]
156pub struct wasmtime_component_valvariant_t {
157 discriminant: wasm_name_t,
158 val: Option<Box<wasmtime_component_val_t>>,
159}
160
161impl From<(&String, &Option<Box<Val>>)> for wasmtime_component_valvariant_t {
162 fn from((discriminant, value): (&String, &Option<Box<Val>>)) -> Self {
163 Self {
164 discriminant: wasm_name_t::from_name(discriminant.clone()),
165 val: value
166 .as_ref()
167 .map(|x| Box::new(wasmtime_component_val_t::from(x.as_ref()))),
168 }
169 }
170}
171
172impl From<&wasmtime_component_valvariant_t> for (String, Option<Box<Val>>) {
173 fn from(value: &wasmtime_component_valvariant_t) -> Self {
174 (
175 String::from_utf8(value.discriminant.clone().take()).unwrap(),
176 value.val.as_ref().map(|x| Box::new(Val::from(x.as_ref()))),
177 )
178 }
179}
180
181#[repr(C)]
182#[derive(Clone)]
183pub struct wasmtime_component_valresult_t {
184 is_ok: bool,
185 val: Option<Box<wasmtime_component_val_t>>,
186}
187
188impl From<&wasmtime_component_valresult_t> for Result<Option<Box<Val>>, Option<Box<Val>>> {
189 fn from(value: &wasmtime_component_valresult_t) -> Self {
190 let val = value.val.as_ref().map(|x| Box::new(Val::from(x.as_ref())));
191
192 match value.is_ok {
193 true => Ok(val),
194 false => Err(val),
195 }
196 }
197}
198
199impl From<&Result<Option<Box<Val>>, Option<Box<Val>>>> for wasmtime_component_valresult_t {
200 fn from(value: &Result<Option<Box<Val>>, Option<Box<Val>>>) -> Self {
201 let (Ok(x) | Err(x)) = value;
202
203 Self {
204 is_ok: value.is_ok(),
205 val: x
206 .as_ref()
207 .map(|x| Box::new(wasmtime_component_val_t::from(x.as_ref()))),
208 }
209 }
210}
211
212#[repr(C, u8)]
213#[derive(Clone)]
214pub enum wasmtime_component_val_t {
215 Bool(bool),
216 S8(i8),
217 U8(u8),
218 S16(i16),
219 U16(u16),
220 S32(i32),
221 U32(u32),
222 S64(i64),
223 U64(u64),
224 F32(f32),
225 F64(f64),
226 Char(u32),
227 String(wasm_name_t),
228 List(wasmtime_component_vallist_t),
229 Record(wasmtime_component_valrecord_t),
230 Tuple(wasmtime_component_valtuple_t),
231 Variant(wasmtime_component_valvariant_t),
232 Enum(wasm_name_t),
233 Option(Option<Box<Self>>),
234 Result(wasmtime_component_valresult_t),
235 Flags(wasmtime_component_valflags_t),
236 Resource(Box<wasmtime_component_resource_any_t>),
237}
238
239impl Default for wasmtime_component_val_t {
240 fn default() -> Self {
241 Self::Bool(false)
242 }
243}
244
245impl From<&wasmtime_component_val_t> for Val {
246 fn from(value: &wasmtime_component_val_t) -> Self {
247 match value {
248 wasmtime_component_val_t::Bool(x) => Val::Bool(*x),
249 wasmtime_component_val_t::S8(x) => Val::S8(*x),
250 wasmtime_component_val_t::U8(x) => Val::U8(*x),
251 wasmtime_component_val_t::S16(x) => Val::S16(*x),
252 wasmtime_component_val_t::U16(x) => Val::U16(*x),
253 wasmtime_component_val_t::S32(x) => Val::S32(*x),
254 wasmtime_component_val_t::U32(x) => Val::U32(*x),
255 wasmtime_component_val_t::S64(x) => Val::S64(*x),
256 wasmtime_component_val_t::U64(x) => Val::U64(*x),
257 wasmtime_component_val_t::F32(x) => Val::Float32(*x),
258 wasmtime_component_val_t::F64(x) => Val::Float64(*x),
259 wasmtime_component_val_t::Char(x) => Val::Char(char::from_u32(*x).unwrap()),
260 wasmtime_component_val_t::String(x) => {
261 Val::String(String::from_utf8(x.clone().take()).unwrap())
262 }
263 wasmtime_component_val_t::List(x) => Val::List(x.into()),
264 wasmtime_component_val_t::Record(x) => Val::Record(x.into()),
265 wasmtime_component_val_t::Tuple(x) => Val::Tuple(x.into()),
266 wasmtime_component_val_t::Variant(x) => {
267 let (a, b) = x.into();
268 Val::Variant(a, b)
269 }
270 wasmtime_component_val_t::Enum(x) => {
271 Val::Enum(String::from_utf8(x.clone().take()).unwrap())
272 }
273 wasmtime_component_val_t::Option(x) => {
274 Val::Option(x.as_ref().map(|x| Box::new(Val::from(x.as_ref()))))
275 }
276 wasmtime_component_val_t::Result(x) => Val::Result(x.into()),
277 wasmtime_component_val_t::Flags(x) => Val::Flags(x.into()),
278 wasmtime_component_val_t::Resource(x) => Val::Resource(x.resource),
279 }
280 }
281}
282
283impl From<&Val> for wasmtime_component_val_t {
284 fn from(value: &Val) -> Self {
285 match value {
286 Val::Bool(x) => wasmtime_component_val_t::Bool(*x),
287 Val::S8(x) => wasmtime_component_val_t::S8(*x),
288 Val::U8(x) => wasmtime_component_val_t::U8(*x),
289 Val::S16(x) => wasmtime_component_val_t::S16(*x),
290 Val::U16(x) => wasmtime_component_val_t::U16(*x),
291 Val::S32(x) => wasmtime_component_val_t::S32(*x),
292 Val::U32(x) => wasmtime_component_val_t::U32(*x),
293 Val::S64(x) => wasmtime_component_val_t::S64(*x),
294 Val::U64(x) => wasmtime_component_val_t::U64(*x),
295 Val::Float32(x) => wasmtime_component_val_t::F32(*x),
296 Val::Float64(x) => wasmtime_component_val_t::F64(*x),
297 Val::Char(x) => wasmtime_component_val_t::Char(*x as _),
298 Val::String(x) => wasmtime_component_val_t::String(wasm_name_t::from_name(x.clone())),
299 Val::List(x) => wasmtime_component_val_t::List(x.as_slice().into()),
300 Val::Record(x) => wasmtime_component_val_t::Record(x.as_slice().into()),
301 Val::Tuple(x) => wasmtime_component_val_t::Tuple(x.as_slice().into()),
302 Val::Variant(discriminant, val) => {
303 wasmtime_component_val_t::Variant((discriminant, val).into())
304 }
305 Val::Enum(x) => wasmtime_component_val_t::Enum(wasm_name_t::from_name(x.clone())),
306 Val::Option(x) => wasmtime_component_val_t::Option(
307 x.as_ref()
308 .map(|x| Box::new(wasmtime_component_val_t::from(x.as_ref()))),
309 ),
310 Val::Result(x) => wasmtime_component_val_t::Result(x.into()),
311 Val::Flags(x) => wasmtime_component_val_t::Flags(x.as_slice().into()),
312 Val::Resource(resource_any) => {
313 wasmtime_component_val_t::Resource(Box::new(wasmtime_component_resource_any_t {
314 resource: *resource_any,
315 }))
316 }
317 Val::Future(_) => todo!(),
318 Val::Stream(_) => todo!(),
319 Val::ErrorContext(_) => todo!(),
320 }
321 }
322}
323
324#[unsafe(no_mangle)]
325pub extern "C" fn wasmtime_component_val_new(
326 src: &mut wasmtime_component_val_t,
327) -> Box<wasmtime_component_val_t> {
328 Box::new(mem::replace(src, wasmtime_component_val_t::default()))
329}
330
331#[unsafe(no_mangle)]
332pub extern "C" fn wasmtime_component_val_free(_dst: Option<Box<wasmtime_component_val_t>>) {}
333
334#[unsafe(no_mangle)]
335pub extern "C" fn wasmtime_component_val_clone(
336 src: &wasmtime_component_val_t,
337 dst: &mut MaybeUninit<wasmtime_component_val_t>,
338) {
339 dst.write(src.clone());
340}
341
342#[unsafe(no_mangle)]
343pub unsafe extern "C" fn wasmtime_component_val_delete(
344 value: &mut ManuallyDrop<wasmtime_component_val_t>,
345) {
346 unsafe {
347 ManuallyDrop::drop(value);
348 }
349}
350
351#[repr(C)]
352#[derive(Clone)]
353pub struct wasmtime_component_resource_any_t {
354 resource: ResourceAny,
355}
356
357#[unsafe(no_mangle)]
358pub extern "C" fn wasmtime_component_resource_any_type(
359 resource: &wasmtime_component_resource_any_t,
360) -> Box<wasmtime_component_resource_type_t> {
361 Box::new(wasmtime_component_resource_type_t {
362 ty: resource.resource.ty(),
363 })
364}
365
366#[unsafe(no_mangle)]
367pub extern "C" fn wasmtime_component_resource_any_clone(
368 resource: &wasmtime_component_resource_any_t,
369) -> Box<wasmtime_component_resource_any_t> {
370 Box::new(wasmtime_component_resource_any_t {
371 resource: resource.resource,
372 })
373}
374
375#[unsafe(no_mangle)]
376pub extern "C" fn wasmtime_component_resource_any_owned(
377 resource: &wasmtime_component_resource_any_t,
378) -> bool {
379 resource.resource.owned()
380}
381
382#[unsafe(no_mangle)]
383pub extern "C" fn wasmtime_component_resource_any_drop(
384 store: WasmtimeStoreContextMut<'_>,
385 resource: &wasmtime_component_resource_any_t,
386) -> Option<Box<wasmtime_error_t>> {
387 handle_result(resource.resource.resource_drop(store), |()| ())
388}
389
390#[unsafe(no_mangle)]
391pub extern "C" fn wasmtime_component_resource_any_delete(
392 _resource: Option<Box<wasmtime_component_resource_any_t>>,
393) {
394}
395
396#[repr(C)]
397pub struct wasmtime_component_resource_host_t {
398 resource: ResourceDynamic,
399}
400
401impl wasmtime_component_resource_host_t {
402 fn resource(&self) -> ResourceDynamic {
404 let rep = self.resource.rep();
405 let ty = self.resource.ty();
406 if self.resource.owned() {
407 ResourceDynamic::new_own(rep, ty)
408 } else {
409 ResourceDynamic::new_borrow(rep, ty)
410 }
411 }
412}
413
414#[unsafe(no_mangle)]
415pub extern "C" fn wasmtime_component_resource_host_new(
416 owned: bool,
417 rep: u32,
418 ty: u32,
419) -> Box<wasmtime_component_resource_host_t> {
420 Box::new(wasmtime_component_resource_host_t {
421 resource: if owned {
422 ResourceDynamic::new_own(rep, ty)
423 } else {
424 ResourceDynamic::new_borrow(rep, ty)
425 },
426 })
427}
428
429#[unsafe(no_mangle)]
430pub extern "C" fn wasmtime_component_resource_host_clone(
431 resource: &wasmtime_component_resource_host_t,
432) -> Box<wasmtime_component_resource_host_t> {
433 Box::new(wasmtime_component_resource_host_t {
434 resource: resource.resource(),
435 })
436}
437
438#[unsafe(no_mangle)]
439pub extern "C" fn wasmtime_component_resource_host_rep(
440 resource: &wasmtime_component_resource_host_t,
441) -> u32 {
442 resource.resource.rep()
443}
444
445#[unsafe(no_mangle)]
446pub extern "C" fn wasmtime_component_resource_host_type(
447 resource: &wasmtime_component_resource_host_t,
448) -> u32 {
449 resource.resource.ty()
450}
451
452#[unsafe(no_mangle)]
453pub extern "C" fn wasmtime_component_resource_host_owned(
454 resource: &wasmtime_component_resource_host_t,
455) -> bool {
456 resource.resource.owned()
457}
458
459#[unsafe(no_mangle)]
460pub extern "C" fn wasmtime_component_resource_host_delete(
461 _resource: Option<Box<wasmtime_component_resource_host_t>>,
462) {
463}
464
465#[unsafe(no_mangle)]
466pub extern "C" fn wasmtime_component_resource_any_to_host(
467 store: WasmtimeStoreContextMut<'_>,
468 resource: &wasmtime_component_resource_any_t,
469 ret: &mut MaybeUninit<Box<wasmtime_component_resource_host_t>>,
470) -> Option<Box<wasmtime_error_t>> {
471 handle_result(
472 resource.resource.try_into_resource_dynamic(store),
473 |resource| {
474 ret.write(Box::new(wasmtime_component_resource_host_t { resource }));
475 },
476 )
477}
478
479#[unsafe(no_mangle)]
480pub extern "C" fn wasmtime_component_resource_host_to_any(
481 store: WasmtimeStoreContextMut<'_>,
482 resource: &wasmtime_component_resource_host_t,
483 ret: &mut MaybeUninit<Box<wasmtime_component_resource_any_t>>,
484) -> Option<Box<wasmtime_error_t>> {
485 handle_result(
486 resource.resource().try_into_resource_any(store),
487 |resource| {
488 ret.write(Box::new(wasmtime_component_resource_any_t { resource }));
489 },
490 )
491}