1 use wasmtime::component::Val;
2 
3 use crate::wasm_name_t;
4 
5 use std::mem;
6 use std::mem::MaybeUninit;
7 use std::ptr;
8 use std::slice;
9 
10 crate::declare_vecs! {
11     (
12         name: wasmtime_component_vallist_t,
13         ty: wasmtime_component_val_t,
14         new: wasmtime_component_vallist_new,
15         empty: wasmtime_component_vallist_new_empty,
16         uninit: wasmtime_component_vallist_new_uninit,
17         copy: wasmtime_component_vallist_copy,
18         delete: wasmtime_component_vallist_delete,
19     )
20     (
21         name: wasmtime_component_valrecord_t,
22         ty: wasmtime_component_valrecord_entry_t,
23         new: wasmtime_component_valrecord_new,
24         empty: wasmtime_component_valrecord_new_empty,
25         uninit: wasmtime_component_valrecord_new_uninit,
26         copy: wasmtime_component_valrecord_copy,
27         delete: wasmtime_component_valrecord_delete,
28     )
29     (
30         name: wasmtime_component_valtuple_t,
31         ty: wasmtime_component_val_t,
32         new: wasmtime_component_valtuple_new,
33         empty: wasmtime_component_valtuple_new_empty,
34         uninit: wasmtime_component_valtuple_new_uninit,
35         copy: wasmtime_component_valtuple_copy,
36         delete: wasmtime_component_valtuple_delete,
37     )
38     (
39         name: wasmtime_component_valflags_t,
40         ty: wasm_name_t,
41         new: wasmtime_component_valflags_new,
42         empty: wasmtime_component_valflags_new_empty,
43         uninit: wasmtime_component_valflags_new_uninit,
44         copy: wasmtime_component_valflags_copy,
45         delete: wasmtime_component_valflags_delete,
46     )
47 }
48 
49 impl From<&wasmtime_component_vallist_t> for Vec<Val> {
50     fn from(value: &wasmtime_component_vallist_t) -> Self {
51         value.as_slice().iter().map(Val::from).collect()
52     }
53 }
54 
55 impl From<&[Val]> for wasmtime_component_vallist_t {
56     fn from(value: &[Val]) -> Self {
57         value
58             .iter()
59             .map(wasmtime_component_val_t::from)
60             .collect::<Vec<_>>()
61             .into()
62     }
63 }
64 
65 #[derive(Clone)]
66 #[repr(C)]
67 pub struct wasmtime_component_valrecord_entry_t {
68     name: wasm_name_t,
69     val: wasmtime_component_val_t,
70 }
71 
72 impl Default for wasmtime_component_valrecord_entry_t {
73     fn default() -> Self {
74         Self {
75             name: wasm_name_t::from_name(String::new()),
76             val: Default::default(),
77         }
78     }
79 }
80 
81 impl From<&wasmtime_component_valrecord_entry_t> for (String, Val) {
82     fn from(value: &wasmtime_component_valrecord_entry_t) -> Self {
83         (
84             String::from_utf8(value.name.clone().take()).unwrap(),
85             Val::from(&value.val),
86         )
87     }
88 }
89 
90 impl From<&(String, Val)> for wasmtime_component_valrecord_entry_t {
91     fn from((name, val): &(String, Val)) -> Self {
92         Self {
93             name: wasm_name_t::from_name(name.clone()),
94             val: wasmtime_component_val_t::from(val),
95         }
96     }
97 }
98 
99 impl From<&wasmtime_component_valrecord_t> for Vec<(String, Val)> {
100     fn from(value: &wasmtime_component_valrecord_t) -> Self {
101         value.as_slice().iter().map(Into::into).collect()
102     }
103 }
104 
105 impl From<&[(String, Val)]> for wasmtime_component_valrecord_t {
106     fn from(value: &[(String, Val)]) -> Self {
107         value
108             .iter()
109             .map(wasmtime_component_valrecord_entry_t::from)
110             .collect::<Vec<_>>()
111             .into()
112     }
113 }
114 
115 impl From<&wasmtime_component_valtuple_t> for Vec<Val> {
116     fn from(value: &wasmtime_component_valtuple_t) -> Self {
117         value.as_slice().iter().map(Val::from).collect()
118     }
119 }
120 
121 impl From<&[Val]> for wasmtime_component_valtuple_t {
122     fn from(value: &[Val]) -> Self {
123         value
124             .iter()
125             .map(wasmtime_component_val_t::from)
126             .collect::<Vec<_>>()
127             .into()
128     }
129 }
130 
131 impl From<&wasmtime_component_valflags_t> for Vec<String> {
132     fn from(value: &wasmtime_component_valflags_t) -> Self {
133         value
134             .clone()
135             .take()
136             .into_iter()
137             .map(|mut x| String::from_utf8(x.take()))
138             .collect::<Result<Vec<_>, _>>()
139             .unwrap()
140     }
141 }
142 
143 impl From<&[String]> for wasmtime_component_valflags_t {
144     fn from(value: &[String]) -> Self {
145         value
146             .iter()
147             .map(|x| wasm_name_t::from_name(x.clone()))
148             .collect::<Vec<_>>()
149             .into()
150     }
151 }
152 
153 #[repr(C)]
154 #[derive(Clone)]
155 pub struct wasmtime_component_valvariant_t {
156     discriminant: wasm_name_t,
157     val: Option<Box<wasmtime_component_val_t>>,
158 }
159 
160 impl From<(&String, &Option<Box<Val>>)> for wasmtime_component_valvariant_t {
161     fn from((discriminant, value): (&String, &Option<Box<Val>>)) -> Self {
162         Self {
163             discriminant: wasm_name_t::from_name(discriminant.clone()),
164             val: value
165                 .as_ref()
166                 .map(|x| Box::new(wasmtime_component_val_t::from(x.as_ref()))),
167         }
168     }
169 }
170 
171 impl From<&wasmtime_component_valvariant_t> for (String, Option<Box<Val>>) {
172     fn from(value: &wasmtime_component_valvariant_t) -> Self {
173         (
174             String::from_utf8(value.discriminant.clone().take()).unwrap(),
175             value.val.as_ref().map(|x| Box::new(Val::from(x.as_ref()))),
176         )
177     }
178 }
179 
180 #[repr(C)]
181 #[derive(Clone)]
182 pub struct wasmtime_component_valresult_t {
183     is_ok: bool,
184     val: Option<Box<wasmtime_component_val_t>>,
185 }
186 
187 impl From<&wasmtime_component_valresult_t> for Result<Option<Box<Val>>, Option<Box<Val>>> {
188     fn from(value: &wasmtime_component_valresult_t) -> Self {
189         let val = value.val.as_ref().map(|x| Box::new(Val::from(x.as_ref())));
190 
191         match value.is_ok {
192             true => Ok(val),
193             false => Err(val),
194         }
195     }
196 }
197 
198 impl From<&Result<Option<Box<Val>>, Option<Box<Val>>>> for wasmtime_component_valresult_t {
199     fn from(value: &Result<Option<Box<Val>>, Option<Box<Val>>>) -> Self {
200         let (Ok(x) | Err(x)) = value;
201 
202         Self {
203             is_ok: value.is_ok(),
204             val: x
205                 .as_ref()
206                 .map(|x| Box::new(wasmtime_component_val_t::from(x.as_ref()))),
207         }
208     }
209 }
210 
211 #[repr(C, u8)]
212 #[derive(Clone)]
213 pub enum wasmtime_component_val_t {
214     Bool(bool),
215     S8(i8),
216     U8(u8),
217     S16(i16),
218     U16(u16),
219     S32(i32),
220     U32(u32),
221     S64(i64),
222     U64(u64),
223     F32(f32),
224     F64(f64),
225     Char(u32),
226     String(wasm_name_t),
227     List(wasmtime_component_vallist_t),
228     Record(wasmtime_component_valrecord_t),
229     Tuple(wasmtime_component_valtuple_t),
230     Variant(wasmtime_component_valvariant_t),
231     Enum(wasm_name_t),
232     Option(Option<Box<Self>>),
233     Result(wasmtime_component_valresult_t),
234     Flags(wasmtime_component_valflags_t),
235 }
236 
237 impl Default for wasmtime_component_val_t {
238     fn default() -> Self {
239         Self::Bool(false)
240     }
241 }
242 
243 impl From<&wasmtime_component_val_t> for Val {
244     fn from(value: &wasmtime_component_val_t) -> Self {
245         match value {
246             wasmtime_component_val_t::Bool(x) => Val::Bool(*x),
247             wasmtime_component_val_t::S8(x) => Val::S8(*x),
248             wasmtime_component_val_t::U8(x) => Val::U8(*x),
249             wasmtime_component_val_t::S16(x) => Val::S16(*x),
250             wasmtime_component_val_t::U16(x) => Val::U16(*x),
251             wasmtime_component_val_t::S32(x) => Val::S32(*x),
252             wasmtime_component_val_t::U32(x) => Val::U32(*x),
253             wasmtime_component_val_t::S64(x) => Val::S64(*x),
254             wasmtime_component_val_t::U64(x) => Val::U64(*x),
255             wasmtime_component_val_t::F32(x) => Val::Float32(*x),
256             wasmtime_component_val_t::F64(x) => Val::Float64(*x),
257             wasmtime_component_val_t::Char(x) => Val::Char(char::from_u32(*x).unwrap()),
258             wasmtime_component_val_t::String(x) => {
259                 Val::String(String::from_utf8(x.clone().take()).unwrap())
260             }
261             wasmtime_component_val_t::List(x) => Val::List(x.into()),
262             wasmtime_component_val_t::Record(x) => Val::Record(x.into()),
263             wasmtime_component_val_t::Tuple(x) => Val::Tuple(x.into()),
264             wasmtime_component_val_t::Variant(x) => {
265                 let (a, b) = x.into();
266                 Val::Variant(a, b)
267             }
268             wasmtime_component_val_t::Enum(x) => {
269                 Val::Enum(String::from_utf8(x.clone().take()).unwrap())
270             }
271             wasmtime_component_val_t::Option(x) => {
272                 Val::Option(x.as_ref().map(|x| Box::new(Val::from(x.as_ref()))))
273             }
274             wasmtime_component_val_t::Result(x) => Val::Result(x.into()),
275             wasmtime_component_val_t::Flags(x) => Val::Flags(x.into()),
276         }
277     }
278 }
279 
280 impl 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) => todo!(),
310             Val::Future(_) => todo!(),
311             Val::Stream(_) => todo!(),
312             Val::ErrorContext(_) => todo!(),
313         }
314     }
315 }
316 
317 #[unsafe(no_mangle)]
318 pub unsafe extern "C" fn wasmtime_component_val_new() -> Box<wasmtime_component_val_t> {
319     Box::new(wasmtime_component_val_t::default())
320 }
321 
322 #[unsafe(no_mangle)]
323 pub unsafe extern "C" fn wasmtime_component_val_delete(value: *mut wasmtime_component_val_t) {
324     unsafe {
325         std::ptr::drop_in_place(value);
326     }
327 }
328