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