1 use {
2     test_programs::p3::{
3         proxy::exports::wasi::http::handler::Guest as Handler,
4         wasi::http::types::{ErrorCode, Request, Response},
5         wit_future, wit_stream,
6     },
7     wit_bindgen::StreamResult,
8 };
9 
10 struct Component;
11 
12 test_programs::p3::proxy::export!(Component);
13 
14 impl Handler for Component {
15     /// Return a response which echoes the request headers, body, and trailers.
16     async fn handle(request: Request) -> Result<Response, ErrorCode> {
17         let headers = request.get_headers();
18         let (_, result_rx) = wit_future::new(|| Ok(()));
19         let (body, trailers) = Request::consume_body(request, result_rx);
20 
21         let (response, _result) = if false {
22             // This is the easy and efficient way to do it...
23             Response::new(headers, Some(body), trailers)
24         } else {
25             // ...but we do it the more difficult, less efficient way here to exercise various component model
26             // features (e.g. `future`s, `stream`s, and post-return asynchronous execution):
27             let (trailers_tx, trailers_rx) = wit_future::new(|| todo!());
28             let (mut pipe_tx, pipe_rx) = wit_stream::new();
29 
30             wit_bindgen::spawn(async move {
31                 let mut body_rx = body;
32                 let mut chunk = Vec::with_capacity(1024);
33                 loop {
34                     let (status, buf) = body_rx.read(chunk).await;
35                     chunk = buf;
36                     match status {
37                         StreamResult::Complete(_) => {
38                             chunk = pipe_tx.write_all(chunk).await;
39                             assert!(chunk.is_empty());
40                         }
41                         StreamResult::Dropped => break,
42                         StreamResult::Cancelled => unreachable!(),
43                     }
44                 }
45 
46                 drop(pipe_tx);
47 
48                 trailers_tx.write(trailers.await).await.unwrap();
49             });
50 
51             Response::new(headers, Some(pipe_rx), trailers_rx)
52         };
53 
54         Ok(response)
55     }
56 }
57 
58 // Unused function; required since this file is built as a `bin`:
59 fn main() {}
60