@@ -100,12 +100,6 @@ pub fn attr_macro_test(_attr: TokenStream, item: TokenStream) -> TokenStream {
100100pub fn attr_macro_http_server ( _attr : TokenStream , item : TokenStream ) -> TokenStream {
101101 let input = parse_macro_input ! ( item as ItemFn ) ;
102102
103- let ( run_async, run_await) = if input. sig . asyncness . is_some ( ) {
104- ( quote ! ( async ) , quote ! ( . await ) )
105- } else {
106- ( quote ! ( ) , quote ! ( ) )
107- } ;
108-
109103 let output = & input. sig . output ;
110104 let inputs = & input. sig . inputs ;
111105 let name = & input. sig . ident ;
@@ -120,63 +114,32 @@ pub fn attr_macro_http_server(_attr: TokenStream, item: TokenStream) -> TokenStr
120114 . into ( ) ;
121115 }
122116
117+ // Delegate to wstd's conditionally-compiled declarative macro.
118+ // The `cfg` checks in `__http_server_export!` run in wstd's context,
119+ // so consumers don't need to define wasip2/wasip3 features themselves.
120+ //
121+ // We use @async/@sync markers so the declarative macro can construct
122+ // the handler call in its own hygiene context (avoiding variable name
123+ // mismatches between proc macro and declarative macro scopes)
124+ // NOTE: we can avoid this once wasm32-wasip3 is an available target
125+ let asyncness = if input. sig . asyncness . is_some ( ) {
126+ quote ! ( @async )
127+ } else {
128+ quote ! ( @sync)
129+ } ;
130+
131+ let run_async = if input. sig . asyncness . is_some ( ) {
132+ quote ! ( async )
133+ } else {
134+ quote ! ( )
135+ } ;
136+
123137 quote ! {
124- struct TheServer ;
125-
126- impl :: wstd:: __internal:: wasip2:: exports:: http:: incoming_handler:: Guest for TheServer {
127- fn handle(
128- request: :: wstd:: __internal:: wasip2:: http:: types:: IncomingRequest ,
129- response_out: :: wstd:: __internal:: wasip2:: http:: types:: ResponseOutparam
130- ) {
131- #( #attrs) *
132- #vis #run_async fn __run( #inputs) #output {
133- #body
134- }
135-
136- let responder = :: wstd:: http:: server:: Responder :: new( response_out) ;
137- :: wstd:: runtime:: block_on( async move {
138- match :: wstd:: http:: request:: try_from_incoming( request) {
139- Ok ( request) => match __run( request) #run_await {
140- Ok ( response) => { responder. respond( response) . await . unwrap( ) } ,
141- Err ( err) => responder. fail( err) ,
142- }
143- Err ( err) => responder. fail( err) ,
144- }
145- } )
146- }
138+ :: wstd:: __http_server_export! {
139+ #asyncness
140+ { #( #attrs) * #vis #run_async fn __run( #inputs) #output { #body } }
147141 }
148142
149- :: wstd:: __internal:: wasip2:: http:: proxy:: export!( TheServer with_types_in :: wstd:: __internal:: wasip2) ;
150-
151- // Provide an actual function named `main`.
152- //
153- // WASI HTTP server components don't use a traditional `main` function.
154- // They export a function named `handle` which takes a `Request`
155- // argument, and which may be called multiple times on the same
156- // instance. To let users write a familiar `fn main` in a file
157- // named src/main.rs, we provide this `wstd::http_server` macro, which
158- // transforms the user's `fn main` into the appropriate `handle`
159- // function.
160- //
161- // However, when the top-level file is named src/main.rs, rustc
162- // requires there to be a function named `main` somewhere in it. This
163- // requirement can be disabled using `#![no_main]`, however we can't
164- // use that automatically because macros can't contain inner
165- // attributes, and we don't want to require users to add `#![no_main]`
166- // in their own code.
167- //
168- // So, we include a definition of a function named `main` here, which
169- // isn't intended to ever be called, and exists just to satify the
170- // requirement for a `main` function.
171- //
172- // Users could use `#![no_main]` if they want to. Or, they could name
173- // their top-level file src/lib.rs and add
174- // ```toml
175- // [lib]
176- // crate-type = ["cdylib"]
177- // ```
178- // to their Cargo.toml. With either of these, this "main" function will
179- // be ignored as dead code.
180143 fn main( ) {
181144 unreachable!( "HTTP server components should be run with `handle` rather than `run`" )
182145 }
0 commit comments