mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
allow custom req/res/client types
This commit is contained in:
parent
1b1e02729e
commit
46e7abf9ba
4 changed files with 84 additions and 5 deletions
|
@ -871,12 +871,15 @@ pub fn slot(args: proc_macro::TokenStream, s: TokenStream) -> TokenStream {
|
|||
/// relative to the prefix (defaults to the function name followed by unique hash)
|
||||
/// - `input`: the encoding for the arguments (defaults to `PostUrl`)
|
||||
/// - `output`: the encoding for the response (defaults to `Json`)
|
||||
/// - `client`: a custom `Client` implementation that will be used for this server fn
|
||||
/// - `encoding`: (legacy, may be deprecated in future) specifies the encoding, which may be one
|
||||
/// of the following (not case sensitive)
|
||||
/// - `"Url"`: `POST` request with URL-encoded arguments and JSON response
|
||||
/// - `"GetUrl"`: `GET` request with URL-encoded arguments and JSON response
|
||||
/// - `"Cbor"`: `POST` request with CBOR-encoded arguments and response
|
||||
/// - `"GetCbor"`: `GET` request with URL-encoded arguments and CBOR response
|
||||
/// - `req` and `res` specify the HTTP request and response types to be used on the server (these
|
||||
/// should usually only be necessary if you are integrating with a server other than Actix/Axum)
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// #[server(
|
||||
|
@ -949,6 +952,8 @@ pub fn server(args: proc_macro::TokenStream, s: TokenStream) -> TokenStream {
|
|||
s.into(),
|
||||
Some(syn::parse_quote!(::leptos::server_fn)),
|
||||
"/api",
|
||||
None,
|
||||
None,
|
||||
) {
|
||||
Err(e) => e.to_compile_error().into(),
|
||||
Ok(s) => s.to_token_stream().into(),
|
||||
|
|
|
@ -34,12 +34,15 @@ use syn::__private::ToTokens;
|
|||
/// relative to the prefix (defaults to the function name followed by unique hash)
|
||||
/// - `input`: the encoding for the arguments (defaults to `PostUrl`)
|
||||
/// - `output`: the encoding for the response (defaults to `Json`)
|
||||
/// - `client`: a custom `Client` implementation that will be used for this server fn
|
||||
/// - `encoding`: (legacy, may be deprecated in future) specifies the encoding, which may be one
|
||||
/// of the following (not case sensitive)
|
||||
/// - `"Url"`: `POST` request with URL-encoded arguments and JSON response
|
||||
/// - `"GetUrl"`: `GET` request with URL-encoded arguments and JSON response
|
||||
/// - `"Cbor"`: `POST` request with CBOR-encoded arguments and response
|
||||
/// - `"GetCbor"`: `GET` request with URL-encoded arguments and CBOR response
|
||||
/// - `req` and `res` specify the HTTP request and response types to be used on the server (these
|
||||
/// should usually only be necessary if you are integrating with a server other than Actix/Axum)
|
||||
/// ```rust,ignore
|
||||
/// #[server(
|
||||
/// name = SomeStructName,
|
||||
|
@ -71,6 +74,8 @@ pub fn server(args: proc_macro::TokenStream, s: TokenStream) -> TokenStream {
|
|||
s.into(),
|
||||
Some(syn::parse_quote!(server_fns)),
|
||||
"/api",
|
||||
None,
|
||||
None,
|
||||
) {
|
||||
Err(e) => e.to_compile_error().into(),
|
||||
Ok(s) => s.to_token_stream().into(),
|
||||
|
|
|
@ -20,3 +20,4 @@ nightly = []
|
|||
ssr = []
|
||||
actix = []
|
||||
axum = []
|
||||
reqwest = []
|
||||
|
|
|
@ -35,6 +35,8 @@ pub fn server_macro_impl(
|
|||
body: TokenStream2,
|
||||
server_fn_path: Option<Path>,
|
||||
default_path: &str,
|
||||
preset_req: Option<Type>,
|
||||
preset_res: Option<Type>,
|
||||
) -> Result<TokenStream2> {
|
||||
let mut body = syn::parse::<ServerFnBody>(body.into())?;
|
||||
|
||||
|
@ -65,7 +67,12 @@ pub fn server_macro_impl(
|
|||
output,
|
||||
fn_path,
|
||||
builtin_encoding,
|
||||
req_ty,
|
||||
res_ty,
|
||||
client,
|
||||
custom_wrapper,
|
||||
} = args;
|
||||
_ = custom_wrapper; // TODO: this should be used to enable custom encodings
|
||||
let prefix = prefix.unwrap_or_else(|| Literal::string(default_path));
|
||||
let fn_path = fn_path.unwrap_or_else(|| Literal::string(""));
|
||||
let input_ident = match &input {
|
||||
|
@ -380,9 +387,16 @@ pub fn server_macro_impl(
|
|||
PathInfo::None => quote! {},
|
||||
};
|
||||
|
||||
// TODO reqwest
|
||||
let client = quote! {
|
||||
#server_fn_path::client::browser::BrowserClient
|
||||
let client = if let Some(client) = client {
|
||||
client.to_token_stream()
|
||||
} else if cfg!(feature = "reqwest") {
|
||||
quote! {
|
||||
#server_fn_path::client::reqwest::ReqwestClient
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#server_fn_path::client::browser::BrowserClient
|
||||
}
|
||||
};
|
||||
|
||||
let req = if !cfg!(feature = "ssr") {
|
||||
|
@ -397,11 +411,16 @@ pub fn server_macro_impl(
|
|||
quote! {
|
||||
#server_fn_path::request::actix::ActixRequest
|
||||
}
|
||||
} else if let Some(req_ty) = req_ty {
|
||||
req_ty.to_token_stream()
|
||||
} else if let Some(req_ty) = preset_req {
|
||||
req_ty.to_token_stream()
|
||||
} else {
|
||||
return Err(syn::Error::new(
|
||||
Span::call_site(),
|
||||
"If the `ssr` feature is enabled, either the `actix` or `axum` \
|
||||
features should also be enabled.",
|
||||
features should also be enabled, or the `req = ` argument should \
|
||||
be provided to specify the request type.",
|
||||
));
|
||||
};
|
||||
let res = if !cfg!(feature = "ssr") {
|
||||
|
@ -416,11 +435,16 @@ pub fn server_macro_impl(
|
|||
quote! {
|
||||
#server_fn_path::response::actix::ActixResponse
|
||||
}
|
||||
} else if let Some(res_ty) = res_ty {
|
||||
res_ty.to_token_stream()
|
||||
} else if let Some(res_ty) = preset_res {
|
||||
res_ty.to_token_stream()
|
||||
} else {
|
||||
return Err(syn::Error::new(
|
||||
Span::call_site(),
|
||||
"If the `ssr` feature is enabled, either the `actix` or `axum` \
|
||||
features should also be enabled.",
|
||||
features should also be enabled, or the `res = ` argument should \
|
||||
be provided to specify the response type.",
|
||||
));
|
||||
};
|
||||
|
||||
|
@ -614,6 +638,10 @@ struct ServerFnArgs {
|
|||
input: Option<Type>,
|
||||
output: Option<Type>,
|
||||
fn_path: Option<Literal>,
|
||||
req_ty: Option<Type>,
|
||||
res_ty: Option<Type>,
|
||||
client: Option<Type>,
|
||||
custom_wrapper: Option<Type>,
|
||||
builtin_encoding: bool,
|
||||
}
|
||||
|
||||
|
@ -628,6 +656,10 @@ impl Parse for ServerFnArgs {
|
|||
// new arguments: can only be keyed by name
|
||||
let mut input: Option<Type> = None;
|
||||
let mut output: Option<Type> = None;
|
||||
let mut req_ty: Option<Type> = None;
|
||||
let mut res_ty: Option<Type> = None;
|
||||
let mut client: Option<Type> = None;
|
||||
let mut custom_wrapper: Option<Type> = None;
|
||||
|
||||
let mut use_key_and_value = false;
|
||||
let mut arg_pos = 0;
|
||||
|
@ -703,6 +735,38 @@ impl Parse for ServerFnArgs {
|
|||
));
|
||||
}
|
||||
output = Some(stream.parse()?);
|
||||
} else if key == "req" {
|
||||
if req_ty.is_some() {
|
||||
return Err(syn::Error::new(
|
||||
key.span(),
|
||||
"keyword argument repeated: `req`",
|
||||
));
|
||||
}
|
||||
req_ty = Some(stream.parse()?);
|
||||
} else if key == "res" {
|
||||
if res_ty.is_some() {
|
||||
return Err(syn::Error::new(
|
||||
key.span(),
|
||||
"keyword argument repeated: `res`",
|
||||
));
|
||||
}
|
||||
res_ty = Some(stream.parse()?);
|
||||
} else if key == "client" {
|
||||
if client.is_some() {
|
||||
return Err(syn::Error::new(
|
||||
key.span(),
|
||||
"keyword argument repeated: `client`",
|
||||
));
|
||||
}
|
||||
client = Some(stream.parse()?);
|
||||
} else if key == "custom" {
|
||||
if custom_wrapper.is_some() {
|
||||
return Err(syn::Error::new(
|
||||
key.span(),
|
||||
"keyword argument repeated: `custom`",
|
||||
));
|
||||
}
|
||||
custom_wrapper = Some(stream.parse()?);
|
||||
} else {
|
||||
return Err(lookahead.error());
|
||||
}
|
||||
|
@ -794,6 +858,10 @@ impl Parse for ServerFnArgs {
|
|||
output,
|
||||
fn_path,
|
||||
builtin_encoding,
|
||||
req_ty,
|
||||
res_ty,
|
||||
client,
|
||||
custom_wrapper,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue