1 use wasmtime::component::{Component, FutureAny, FutureReader, Linker, StreamAny, StreamReader};
2 use wasmtime::{Config, Engine, Result, Store};
3 
4 #[test]
5 fn simple_type_conversions() {
6     let engine = Engine::default();
7     let mut store = Store::new(&engine, ());
8 
9     let f = FutureReader::new(&mut store, async { anyhow::Ok(10_u32) });
10     let f = f.try_into_future_any(&mut store).unwrap();
11     assert!(f.clone().try_into_future_reader::<()>().is_err());
12     assert!(f.clone().try_into_future_reader::<u64>().is_err());
13     let f = f.try_into_future_reader::<u32>().unwrap();
14     f.try_into_future_any(&mut store).unwrap().close(&mut store);
15 
16     let s = StreamReader::new(&mut store, vec![10_u32]);
17     let s = s.try_into_stream_any(&mut store).unwrap();
18     assert!(s.clone().try_into_stream_reader::<()>().is_err());
19     assert!(s.clone().try_into_stream_reader::<u64>().is_err());
20     let s = s.try_into_stream_reader::<u32>().unwrap();
21     s.try_into_stream_any(&mut store).unwrap().close(&mut store);
22 }
23 
24 #[test]
25 #[cfg_attr(miri, ignore)]
26 fn simple_type_assertions() -> Result<()> {
27     let mut config = Config::new();
28     config.wasm_component_model_async(true);
29     let engine = Engine::new(&config)?;
30     let mut store = Store::new(&engine, ());
31 
32     let component = Component::new(
33         &engine,
34         r#"
35         (component
36             (type $f (future u32))
37             (type $s (stream u32))
38             (core func $mk-f (canon future.new $f))
39             (core func $mk-s (canon stream.new $s))
40 
41             (core module $m
42                 (import "" "mk-f" (func $mk-f (result i64)))
43                 (import "" "mk-s" (func $mk-s (result i64)))
44 
45                 (func (export "x") (param i32) (result i32) local.get 0)
46 
47                 (func (export "mk-f") (result i32)
48                     (i32.wrap_i64 (call $mk-f)))
49                 (func (export "mk-s") (result i32)
50                     (i32.wrap_i64 (call $mk-s)))
51             )
52             (core instance $i (instantiate $m
53                 (with "" (instance
54                     (export "mk-f" (func $mk-f))
55                     (export "mk-s" (func $mk-s))
56                 ))
57             ))
58             (func (export "f") (param "f" $f) (result $f)
59                 (canon lift (core func $i "x")))
60             (func (export "s") (param "s" $s) (result $s)
61                 (canon lift (core func $i "x")))
62             (func (export "mk-f") (result $f)
63                 (canon lift (core func $i "mk-f")))
64             (func (export "mk-s") (result $s)
65                 (canon lift (core func $i "mk-s")))
66         )
67         "#,
68     )?;
69 
70     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
71 
72     let f_t_t =
73         instance.get_typed_func::<(FutureReader<u32>,), (FutureReader<u32>,)>(&mut store, "f")?;
74     let f_t_a = instance.get_typed_func::<(FutureReader<u32>,), (FutureAny,)>(&mut store, "f")?;
75     let f_a_t = instance.get_typed_func::<(FutureAny,), (FutureReader<u32>,)>(&mut store, "f")?;
76     let f_a_a = instance.get_typed_func::<(FutureAny,), (FutureAny,)>(&mut store, "f")?;
77 
78     let s_t_t =
79         instance.get_typed_func::<(StreamReader<u32>,), (StreamReader<u32>,)>(&mut store, "s")?;
80     let s_t_a = instance.get_typed_func::<(StreamReader<u32>,), (StreamAny,)>(&mut store, "s")?;
81     let s_a_t = instance.get_typed_func::<(StreamAny,), (StreamReader<u32>,)>(&mut store, "s")?;
82     let s_a_a = instance.get_typed_func::<(StreamAny,), (StreamAny,)>(&mut store, "s")?;
83 
84     let mk_f_t = instance.get_typed_func::<(), (FutureReader<u32>,)>(&mut store, "mk-f")?;
85     let mk_f_a = instance.get_typed_func::<(), (FutureAny,)>(&mut store, "mk-f")?;
86     let mk_s_t = instance.get_typed_func::<(), (StreamReader<u32>,)>(&mut store, "mk-s")?;
87     let mk_s_a = instance.get_typed_func::<(), (StreamAny,)>(&mut store, "mk-s")?;
88 
89     assert!(instance.get_typed_func::<(), ()>(&mut store, "f").is_err());
90     assert!(
91         instance
92             .get_typed_func::<(u32,), (FutureReader<u32>,)>(&mut store, "f")
93             .is_err()
94     );
95     assert!(
96         instance
97             .get_typed_func::<(FutureReader<u32>,), (u32,)>(&mut store, "f")
98             .is_err()
99     );
100     assert!(
101         instance
102             .get_typed_func::<(FutureReader<()>,), (FutureReader<u32>,)>(&mut store, "f")
103             .is_err()
104     );
105     assert!(
106         instance
107             .get_typed_func::<(FutureReader<u64>,), (FutureReader<u32>,)>(&mut store, "f")
108             .is_err()
109     );
110 
111     assert!(instance.get_typed_func::<(), ()>(&mut store, "s").is_err());
112     assert!(
113         instance
114             .get_typed_func::<(u32,), (StreamReader<u32>,)>(&mut store, "s")
115             .is_err()
116     );
117     assert!(
118         instance
119             .get_typed_func::<(StreamReader<u32>,), (u32,)>(&mut store, "s")
120             .is_err()
121     );
122     assert!(
123         instance
124             .get_typed_func::<(StreamReader<()>,), (StreamReader<u32>,)>(&mut store, "s")
125             .is_err()
126     );
127     assert!(
128         instance
129             .get_typed_func::<(StreamReader<u64>,), (StreamReader<u32>,)>(&mut store, "s")
130             .is_err()
131     );
132 
133     let roundtrip = |store: &mut Store<()>, f: FutureReader<u32>| -> Result<()> {
134         let (f,) = f_t_t.call(&mut *store, (f,))?;
135         f_t_t.post_return(&mut *store)?;
136         let (f,) = f_t_a.call(&mut *store, (f,))?;
137         f_t_a.post_return(&mut *store)?;
138         let (f,) = f_a_a.call(&mut *store, (f,))?;
139         f_a_a.post_return(&mut *store)?;
140         let (mut f,) = f_a_t.call(&mut *store, (f,))?;
141         f_a_t.post_return(&mut *store)?;
142         f.close(&mut *store);
143         Ok(())
144     };
145 
146     let f = FutureReader::new(&mut store, async { anyhow::Ok(10_u32) });
147     roundtrip(&mut store, f)?;
148 
149     let (f,) = mk_f_t.call(&mut store, ())?;
150     mk_f_t.post_return(&mut store)?;
151     roundtrip(&mut store, f)?;
152 
153     let (f,) = mk_f_a.call(&mut store, ())?;
154     mk_f_a.post_return(&mut store)?;
155     let f = f.try_into_future_reader::<u32>()?;
156     roundtrip(&mut store, f)?;
157 
158     let roundtrip = |store: &mut Store<()>, s: StreamReader<u32>| -> Result<()> {
159         let (s,) = s_t_t.call(&mut *store, (s,))?;
160         s_t_t.post_return(&mut *store)?;
161         let (s,) = s_t_a.call(&mut *store, (s,))?;
162         s_t_a.post_return(&mut *store)?;
163         let (s,) = s_a_a.call(&mut *store, (s,))?;
164         s_a_a.post_return(&mut *store)?;
165         let (mut s,) = s_a_t.call(&mut *store, (s,))?;
166         s_a_t.post_return(&mut *store)?;
167         s.close(&mut *store);
168         Ok(())
169     };
170 
171     let s = StreamReader::new(&mut store, vec![10_u32]);
172     roundtrip(&mut store, s)?;
173 
174     let (s,) = mk_s_t.call(&mut store, ())?;
175     mk_s_t.post_return(&mut store)?;
176     roundtrip(&mut store, s)?;
177 
178     let (s,) = mk_s_a.call(&mut store, ())?;
179     mk_s_a.post_return(&mut store)?;
180     let s = s.try_into_stream_reader::<u32>()?;
181     roundtrip(&mut store, s)?;
182 
183     Ok(())
184 }
185