Skip to content

Commit c9eb516

Browse files
test(jco): add async future lift tests future tx component
1 parent d979322 commit c9eb516

File tree

5 files changed

+924
-80
lines changed

5 files changed

+924
-80
lines changed
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
use std::sync::atomic::AtomicU32;
2+
3+
mod bindings {
4+
use super::Component;
5+
wit_bindgen::generate!({
6+
world: "future-tx",
7+
with: {
8+
"jco:test-components/get-future-async/example-guest-resource": generate,
9+
}
10+
});
11+
export!(Component);
12+
}
13+
14+
use wit_bindgen::{FutureReader, StreamReader};
15+
16+
use bindings::exports::jco::test_components::get_future_async;
17+
use bindings::exports::jco::test_components::get_future_async::GuestExampleGuestResource;
18+
use bindings::jco::test_components::resources::ExampleResource;
19+
use bindings::wit_future::FuturePayload;
20+
use bindings::{wit_future, wit_stream};
21+
22+
struct Component;
23+
24+
static RESOURCE_DISPOSE_COUNT: AtomicU32 = AtomicU32::new(0);
25+
26+
/// Guest-local implementation of `example-resource`
27+
///
28+
/// This resource is returned by component exported fucntions, but note
29+
/// that is is *distinct* from the resource that is provided by the host
30+
/// and passed in.
31+
///
32+
/// This component can look and behave and be linked to the external resource
33+
/// implementation (forwarding calls to it), but it is *not* the same.
34+
///
35+
pub struct ExR(u32);
36+
37+
impl get_future_async::GuestExampleGuestResource for ExR {
38+
fn new(id: u32) -> Self {
39+
ExR(id)
40+
}
41+
42+
fn get_id(&self) -> u32 {
43+
self.0
44+
}
45+
46+
async fn get_id_async(&self) -> u32 {
47+
self.0
48+
}
49+
}
50+
51+
// NOTE: we need a default implementation
52+
impl Default for get_future_async::ExampleRecord {
53+
fn default() -> Self {
54+
get_future_async::ExampleRecord {
55+
id: 0,
56+
id_str: "<default>".into(),
57+
}
58+
}
59+
}
60+
61+
impl Drop for ExR {
62+
fn drop(&mut self) {
63+
RESOURCE_DISPOSE_COUNT.fetch_add(1, std::sync::atomic::Ordering::Release);
64+
}
65+
}
66+
67+
impl get_future_async::Guest for Component {
68+
type ExampleGuestResource = ExR;
69+
70+
async fn get_future_bool(v: bool) -> FutureReader<bool> {
71+
future_value_async(v)
72+
}
73+
74+
async fn get_future_u32(v: u32) -> FutureReader<u32> {
75+
future_value_async(v)
76+
}
77+
78+
async fn get_future_s32(v: i32) -> FutureReader<i32> {
79+
future_value_async(v)
80+
}
81+
82+
async fn get_future_u8(vals: u8) -> FutureReader<u8> {
83+
future_value_async(vals)
84+
}
85+
86+
async fn get_future_s8(vals: i8) -> FutureReader<i8> {
87+
future_value_async(vals)
88+
}
89+
90+
async fn get_future_u16(vals: u16) -> FutureReader<u16> {
91+
future_value_async(vals)
92+
}
93+
94+
async fn get_future_s16(vals: i16) -> FutureReader<i16> {
95+
future_value_async(vals)
96+
}
97+
98+
async fn get_future_u64(vals: u64) -> FutureReader<u64> {
99+
future_value_async(vals)
100+
}
101+
102+
async fn get_future_s64(vals: i64) -> FutureReader<i64> {
103+
future_value_async(vals)
104+
}
105+
106+
async fn get_future_f32(vals: f32) -> FutureReader<f32> {
107+
future_value_async(vals)
108+
}
109+
110+
async fn get_future_f64(vals: f64) -> FutureReader<f64> {
111+
future_value_async(vals)
112+
}
113+
114+
async fn get_future_string(vals: String) -> FutureReader<String> {
115+
future_value_async(vals)
116+
}
117+
118+
async fn get_future_record(
119+
vals: get_future_async::ExampleRecord,
120+
) -> FutureReader<get_future_async::ExampleRecord> {
121+
future_value_async(vals)
122+
}
123+
124+
async fn get_future_variant(
125+
v: get_future_async::ExampleVariant,
126+
) -> FutureReader<get_future_async::ExampleVariant> {
127+
future_value_async(v)
128+
}
129+
130+
async fn get_future_tuple(v: (u32, i32, String)) -> FutureReader<(u32, i32, String)> {
131+
future_value_async(v)
132+
}
133+
134+
async fn get_future_flags(
135+
v: get_future_async::ExampleFlags,
136+
) -> FutureReader<get_future_async::ExampleFlags> {
137+
future_value_async(v)
138+
}
139+
140+
async fn get_future_enum(
141+
vals: get_future_async::ExampleEnum,
142+
) -> FutureReader<get_future_async::ExampleEnum> {
143+
future_value_async(vals)
144+
}
145+
146+
async fn get_future_option_string(vals: Option<String>) -> FutureReader<Option<String>> {
147+
future_value_async(vals)
148+
}
149+
150+
async fn get_future_result_string(
151+
vals: Result<String, String>,
152+
) -> FutureReader<Result<String, String>> {
153+
future_value_async(vals)
154+
}
155+
156+
async fn get_future_list_u8(vals: Vec<u8>) -> FutureReader<Vec<u8>> {
157+
future_value_async(vals)
158+
}
159+
160+
async fn get_future_list_string(vals: Vec<String>) -> FutureReader<Vec<String>> {
161+
future_value_async(vals)
162+
}
163+
164+
async fn get_future_list_record(
165+
vals: Vec<get_future_async::ExampleRecord>,
166+
) -> FutureReader<Vec<get_future_async::ExampleRecord>> {
167+
future_value_async(vals)
168+
}
169+
170+
async fn get_future_fixed_list_u32(vals: [u32; 5]) -> FutureReader<[u32; 5]> {
171+
future_value_async(vals)
172+
}
173+
174+
async fn get_future_example_resource_own(
175+
v: u32,
176+
) -> FutureReader<get_future_async::ExampleGuestResource> {
177+
future_value_async(get_future_async::ExampleGuestResource::new(ExR::new(v)))
178+
}
179+
180+
fn get_example_resource_own_disposes() -> u32 {
181+
RESOURCE_DISPOSE_COUNT.load(std::sync::atomic::Ordering::Acquire)
182+
}
183+
184+
async fn get_future_future_string(v: String) -> FutureReader<FutureReader<String>> {
185+
let (tx, rx) = wit_future::new(|| unreachable!());
186+
wit_bindgen::spawn(async move {
187+
let (nested_tx, nested_rx) = wit_future::new(|| unreachable!());
188+
// NOTE: order here matters, we must first write the inner rx out before actually filling it
189+
let _ = tx.write(nested_rx).await;
190+
let _ = nested_tx.write(v).await;
191+
});
192+
rx
193+
}
194+
195+
async fn get_future_example_resource_own_attr(v: ExampleResource) -> FutureReader<u32> {
196+
let (tx, rx) = wit_future::new(|| unreachable!());
197+
wit_bindgen::spawn(async move {
198+
let _ = tx.write(v.get_id()).await;
199+
});
200+
rx
201+
}
202+
203+
// NOTE: Spool means this function will replay received values
204+
async fn get_future_stream_string_spool(
205+
vals: Vec<String>,
206+
) -> FutureReader<StreamReader<String>> {
207+
let (future_tx, future_rx) = wit_future::new(|| unreachable!());
208+
let (mut stream_tx, stream_rx) = wit_stream::new();
209+
wit_bindgen::spawn(async move {
210+
let _ = future_tx.write(stream_rx).await;
211+
for v in vals {
212+
stream_tx.write_one(v).await;
213+
}
214+
});
215+
future_rx
216+
}
217+
218+
async fn get_future_stream_string(
219+
v: StreamReader<String>,
220+
) -> FutureReader<StreamReader<String>> {
221+
let (future_tx, future_rx) = wit_future::new(|| unreachable!());
222+
wit_bindgen::spawn(async move {
223+
let _ = future_tx.write(v).await;
224+
});
225+
future_rx
226+
}
227+
}
228+
229+
fn future_value_async<T: FuturePayload>(v: T) -> FutureReader<T> {
230+
let (tx, rx) = wit_future::new(|| unreachable!("default value should not be used"));
231+
wit_bindgen::spawn(async move {
232+
let _ = tx.write(v).await;
233+
});
234+
rx
235+
}
236+
237+
// Stub only to ensure this works as a binary
238+
fn main() {}

0 commit comments

Comments
 (0)