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