diff --git a/packages/server-macro/src/lib.rs b/packages/server-macro/src/lib.rs index b8b3d2b0ad..3f1c665baf 100644 --- a/packages/server-macro/src/lib.rs +++ b/packages/server-macro/src/lib.rs @@ -31,23 +31,85 @@ use syn::{__private::ToTokens, parse_quote}; /// /// ## Named Arguments /// -/// You can any combination of the following named arguments: +/// You can use any combination of the following named arguments: /// - `name`: sets the identifier for the server function’s type, which is a struct created -/// to hold the arguments (defaults to the function identifier in PascalCase) -/// - `prefix`: a prefix at which the server function handler will be mounted (defaults to `/api`) +/// to hold the arguments (defaults to the function identifier in PascalCase). +/// Example: `name = MyServerFunction`. +/// - `prefix`: a prefix at which the server function handler will be mounted (defaults to `/api`). +/// Example: `prefix = "/my_api"`. /// - `endpoint`: specifies the exact path at which the server function handler will be mounted, -/// 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 +/// relative to the prefix (defaults to the function name followed by unique hash). +/// Example: `endpoint = "my_fn"`. +/// - `input`: the encoding for the arguments (defaults to `PostUrl`). +/// - The `input` argument specifies how the function arguments are encoded for transmission. +/// - Acceptable values include: +/// - `PostUrl`: A `POST` request with URL-encoded arguments, suitable for form-like submissions. +/// - `Json`: A `POST` request where the arguments are encoded as JSON. This is a common choice for modern APIs. +/// - `Cbor`: A `POST` request with CBOR-encoded arguments, useful for binary data transmission with compact encoding. +/// - `GetUrl`: A `GET` request with URL-encoded arguments, suitable for simple queries or when data fits in the URL. +/// - `GetCbor`: A `GET` request with CBOR-encoded arguments, useful for query-style APIs when the payload is binary. +/// - `output`: the encoding for the response (defaults to `Json`). +/// - The `output` argument specifies how the server should encode the response data. +/// - Acceptable values include: +/// - `Json`: A response encoded as JSON (default). This is ideal for most web applications. +/// - `Cbor`: A response encoded in the CBOR format for efficient, binary-encoded data. +/// - `client`: a custom `Client` implementation that will be used for this server function. This allows +/// customization of the client-side behavior if needed. /// - `encoding`: (legacy, may be deprecated in future) specifies the encoding, which may be one -/// of the following (not case sensitive) +/// 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) +/// - `req` and `res`: specify the HTTP request and response types to be used on the server. These +/// are typically necessary if you are integrating with a custom server framework (other than Actix/Axum). +/// Example: `req = SomeRequestType`, `res = SomeResponseType`. +/// +/// ## Advanced Usage of `input` and `output` Fields +/// +/// The `input` and `output` fields allow you to customize how arguments and responses are encoded and decoded. +/// These fields impose specific trait bounds on the types you use. Here are detailed examples for different scenarios: +/// +/// ### `output = StreamingJson` +/// +/// Setting the `output` type to `StreamingJson` requires the return type to implement `From>`, +/// where `T` implements `serde::Serialize` and `serde::de::DeserializeOwned`. +/// +/// ```rust,ignore +/// #[server(output = StreamingJson)] +/// pub async fn json_stream_fn() -> Result, ServerFnError> { +/// todo!() +/// } +/// ``` +/// +/// ### `output = StreamingText` +/// +/// Setting the `output` type to `StreamingText` requires the return type to implement `From`. +/// +/// ```rust,ignore +/// #[server(output = StreamingText)] +/// pub async fn text_stream_fn() -> Result { +/// todo!() +/// } +/// ``` +/// +/// ### `output = PostUrl` +/// +/// Setting the `output` type to `PostUrl` requires the return type to implement `Serialize` and `Deserialize`. +/// Note that this uses `serde_qs`, which imposes the following constraints: +/// - The structure must be less than 5 levels deep. +/// - The structure must not contain any `serde(flatten)` attributes. +/// +/// ```rust,ignore +/// #[server(output = PostUrl)] +/// pub async fn form_fn() -> Result { +/// todo!() +/// } +/// ``` +/// +/// These examples illustrate how the `output` type impacts the bounds and expectations for your server function. Ensure your return types comply with these requirements. +/// +/// /// ```rust,ignore /// #[server( /// name = SomeStructName,