diff --git a/website/src/content/current-sidebar.ts b/website/src/content/current-sidebar.ts index b6e8393692f..edc19ff52a1 100644 --- a/website/src/content/current-sidebar.ts +++ b/website/src/content/current-sidebar.ts @@ -209,6 +209,13 @@ const sidebar: SidebarItem[] = [ [], "preview", ), + createLibraryReferenceStructure( + "emitters/clients/http-client-rust", + "Rust", + false, + [], + "preview", + ), ], }, { diff --git a/website/src/content/docs/docs/emitters/clients/http-client-rust/reference/decorators.md b/website/src/content/docs/docs/emitters/clients/http-client-rust/reference/decorators.md new file mode 100644 index 00000000000..5286f905872 --- /dev/null +++ b/website/src/content/docs/docs/emitters/clients/http-client-rust/reference/decorators.md @@ -0,0 +1,85 @@ +--- +title: "Decorators" +description: "Decorators supported by @azure-tools/typespec-rust" +toc_min_heading_level: 2 +toc_max_heading_level: 3 +--- + +The Rust emitter does not define its own TypeSpec decorators. Instead it recognizes a set of decorators from [`@azure-tools/typespec-client-generator-core`](https://www.npmjs.com/package/@azure-tools/typespec-client-generator-core) (TCGC) and from the TypeSpec standard library that influence how the generated Rust code looks. The supported decorators are documented below. + +## `@clientOption` {#clientOption} + +**Source:** `Azure.ClientGenerator.Core` (from `@azure-tools/typespec-client-generator-core`) + +The `@@clientOption` decorator passes emitter-specific named options to a client, an operation, or a model property. The Rust emitter recognizes the following named options. + +### On clients: `omitEndpointMethod` + +**Type:** `boolean` + +When `true`, the `endpoint()` accessor method is not generated on the client struct. Use this when you need to write the method by hand in a customization layer. + +```typespec +@@clientOption(MyClient, "omitEndpointMethod", true); +``` + +### On paging operations: `forcePageIterator` + +**Type:** `boolean` + +When `true`, a paging operation returns a `PageIterator` instead of the default `Pager`. A `PageIterator` asynchronously yields individual items across all pages, while a `Pager` yields one page at a time. + +```typespec +@@clientOption(MyClient.listItems, "forcePageIterator", true); +``` + +### On model properties: `deserialize_with` + +**Type:** `string` + +Specifies the path to a custom Rust deserialization function for the annotated model property. The value must be a valid Rust path (e.g. `"my_crate::serde_helpers::deserialize_foo"`). The generated code emits `#[serde(deserialize_with = "…")]` on the field. + +```typespec +@@clientOption(MyModel.myProperty, "deserialize_with", "my_crate::serde_helpers::deserialize_foo"); +``` + +### On model properties: `serialize_with` + +**Type:** `string` + +Specifies the path to a custom Rust serialization function for the annotated model property. The value must be a valid Rust path (e.g. `"my_crate::serde_helpers::serialize_foo"`). The generated code emits `#[serde(serialize_with = "…")]` on the field. + +```typespec +@@clientOption(MyModel.myProperty, "serialize_with", "my_crate::serde_helpers::serialize_foo"); +``` + +## `@deserializeEmptyStringAsNull` {#deserializeEmptyStringAsNull} + +**Source:** `Azure.ClientGenerator.Core` (from `@azure-tools/typespec-client-generator-core`) + +When applied to a model property, empty string values (`""`) received from the service are deserialized as `None` instead of `Some("")`. Useful for services that use an empty string to represent the absence of a value. + +```typespec +@@deserializeEmptyStringAsNull(MyModel.optionalName); +``` + +## `@clientName` {#clientName} + +**Source:** `Azure.ClientGenerator.Core` (from `@azure-tools/typespec-client-generator-core`) + +Overrides the auto-generated Rust name for a client or an operation. The provided name is used verbatim, bypassing the emitter's automatic naming rules (such as prefixing paging methods with `list_` or LRO methods with `begin_`). + +```typespec +@@clientName(MyClient.get_items, "fetch_items", "rust"); +``` + +## XML decorators {#xml-decorators} + +The Rust emitter honours the following TypeSpec XML decorators when generating (de)serialization code for XML services: + +| Decorator | Source | Effect on generated Rust | +| --------- | ------ | ------------------------ | +| `@encodedName("application/xml", …)` | `TypeSpec` | Sets the XML element name used in `#[serde(rename = "…")]` for the field. | +| `TypeSpec.Xml.@name` | `@typespec/xml` | Sets the XML element or attribute name for the field. | +| `TypeSpec.Xml.@attribute` | `@typespec/xml` | Marks the field as an XML attribute (`#[serde(rename = "@…")]`). | +| `TypeSpec.Xml.@unwrapped` | `@typespec/xml` | For array fields, child elements are emitted as direct children (unwrapped list). For string fields, the value is emitted as text content. | diff --git a/website/src/content/docs/docs/emitters/clients/http-client-rust/reference/emitter.md b/website/src/content/docs/docs/emitters/clients/http-client-rust/reference/emitter.md new file mode 100644 index 00000000000..bf4f1b97e7b --- /dev/null +++ b/website/src/content/docs/docs/emitters/clients/http-client-rust/reference/emitter.md @@ -0,0 +1,83 @@ +--- +title: "Emitter usage" +--- + +## Emitter usage + +1. Via the command line + +```bash +tsp compile . --emit=@azure-tools/typespec-rust +``` + +2. Via the config + +```yaml +emit: + - "@azure-tools/typespec-rust" +``` + +The config can be extended with options as follows: + +```yaml +emit: + - "@azure-tools/typespec-rust" +options: + "@azure-tools/typespec-rust": + option: value +``` + +## Emitter options + +### `emitter-output-dir` + +**Type:** `absolutePath` + +Defines the emitter output directory. Defaults to `{output-dir}/@azure-tools/typespec-rust`. +See [Configuring output directory for more info](https://typespec.io/docs/handbook/configuration/configuration/#configuring-output-directory) + +### `crate-name` + +**Type:** `string` + +**Required** + +The name of the generated Rust crate as it appears in `Cargo.toml`. + +### `crate-version` + +**Type:** `string` + +**Required** + +The version string of the generated Rust crate as it appears in `Cargo.toml` (e.g. `"0.1.0"`). + +### `omit-constructors` + +**Type:** `boolean` + +Set to `true` to skip generating constructors and their associated options type for all client structs. Useful when constructors are hand-written in a `client.tsp` customization layer. The default value is `false`. + +### `overwrite-cargo-toml` + +**Type:** `boolean` + +Set to `true` to overwrite an existing `Cargo.toml` file in the output directory. By default the emitter skips re-generating `Cargo.toml` when one already exists, so that hand-edited dependency entries are preserved. The default value is `false`. + +### `overwrite-lib-rs` + +**Type:** `boolean` + +Set to `true` to overwrite an existing `lib.rs` file in the output directory. By default the emitter skips re-generating `lib.rs` so that hand-written module declarations are preserved. The default value is `false`. + +### `emit-error-traits` + +**Type:** `boolean` + +Set to `true` to emit `TryFrom` trait implementations for terminal error types. This allows callers to convert a generic `azure_core::Error` into a strongly-typed error model. The default value is `false`. + +### `temp-omit-doc-links` + +**Type:** `boolean` + +Set to `true` to omit intra-doc links in the generated Rust documentation comments. This is a temporary workaround for cases where the generated link targets are not yet resolvable by `rustdoc`. The default value is `false`. diff --git a/website/src/content/docs/docs/emitters/clients/http-client-rust/reference/index.mdx b/website/src/content/docs/docs/emitters/clients/http-client-rust/reference/index.mdx new file mode 100644 index 00000000000..1356e7bfa4f --- /dev/null +++ b/website/src/content/docs/docs/emitters/clients/http-client-rust/reference/index.mdx @@ -0,0 +1,37 @@ +--- +title: Overview +sidebar_position: 0 +toc_min_heading_level: 2 +toc_max_heading_level: 3 +--- + +import { Tabs, TabItem } from "@astrojs/starlight/components"; + +TypeSpec library for emitting HTTP client libraries for Rust. + +## Install + + + + +```bash +npm install @azure-tools/typespec-rust +``` + + + + +```bash +npm install --save-peer @azure-tools/typespec-rust +``` + + + + +## Emitter usage + +[See documentation](./emitter.md) + +## Supported decorators + +[See documentation](./decorators.md) diff --git a/website/src/content/docs/docs/emitters/clients/introduction.mdx b/website/src/content/docs/docs/emitters/clients/introduction.mdx index 9e43405f6d7..5a46756325a 100644 --- a/website/src/content/docs/docs/emitters/clients/introduction.mdx +++ b/website/src/content/docs/docs/emitters/clients/introduction.mdx @@ -8,7 +8,7 @@ import { Aside, Steps } from "@astrojs/starlight/components"; ### Introduction -This guide will walk you through the process of using different client emitters (JavaScript, Python, Java, C#) to generate HTTP clients from TypeSpec. Please note that all client emitters are currently in **preview** and are subject to changes in future versions. +This guide will walk you through the process of using different client emitters (JavaScript, Python, Java, C#, Rust) to generate HTTP clients from TypeSpec. Please note that all client emitters are currently in **preview** and are subject to changes in future versions. By following this guide, you will learn: @@ -20,12 +20,13 @@ By following this guide, you will learn: The client emitters are defined in the `package.json` file within your project. -| **Emitter Name** | **Language** | **Version** | -| ---------------------------- | ------------ | -------------------------------------------------------------- | -| @typespec/http-client-js | JavaScript | ![](https://img.shields.io/npm/v/@typespec/http-client-js) | -| @typespec/http-client-python | Python | ![](https://img.shields.io/npm/v/@typespec/http-client-python) | -| @typespec/http-client-java | Java | ![](https://img.shields.io/npm/v/@typespec/http-client-java) | -| @typespec/http-client-csharp | C# | ![](https://img.shields.io/npm/v/@typespec/http-client-csharp) | +| **Emitter Name** | **Language** | **Version** | +| ----------------------------- | ------------ | --------------------------------------------------------------- | +| @typespec/http-client-js | JavaScript | ![](https://img.shields.io/npm/v/@typespec/http-client-js) | +| @typespec/http-client-python | Python | ![](https://img.shields.io/npm/v/@typespec/http-client-python) | +| @typespec/http-client-java | Java | ![](https://img.shields.io/npm/v/@typespec/http-client-java) | +| @typespec/http-client-csharp | C# | ![](https://img.shields.io/npm/v/@typespec/http-client-csharp) | +| @azure-tools/typespec-rust | Rust | ![](https://img.shields.io/npm/v/@azure-tools/typespec-rust) | Below is an example of the `package.json` snippet where client emitters are defined: @@ -35,6 +36,7 @@ Below is an example of the `package.json` snippet where client emitters are defi "@typespec/http-client-java": "^0.1.9", "@typespec/http-client-python": "^0.6.6", "@typespec/http-client-js": "^0.38.1", + "@azure-tools/typespec-rust": "^0.41.0", } ``` @@ -86,6 +88,31 @@ Before using the Java client emitter, ensure the following dependencies are inst Before using the C# client emitter, ensure that the [.NET 8.0 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) (or higher) is installed. Full configuration options can be found in the [C# Client Emitter README](https://github.com/microsoft/typespec/blob/main/packages/http-client-csharp/readme.md#configuration) +### Rust Client Emitter Settings + +Before using the Rust client emitter, ensure that the [Rust toolchain](https://www.rust-lang.org/tools/install) is installed. + +The following options can be set under `options["@azure-tools/typespec-rust"]` in your `tspconfig.yaml`: + +| Option | Type | Default | Description | +| ----------------------- | ------- | ------- | ------------------------------------------------------------------ | +| `crate-name` | string | — | Name of the generated Rust crate. | +| `crate-version` | string | — | Version of the generated Rust crate. | +| `omit-constructors` | boolean | `false` | When `true`, constructors are not generated for model types. | +| `overwrite-cargo-toml` | boolean | `false` | When `true`, an existing `Cargo.toml` will be overwritten. | +| `overwrite-lib-rs` | boolean | `false` | When `true`, an existing `lib.rs` will be overwritten. | +| `emit-error-traits` | boolean | `false` | When `true`, error trait implementations are emitted for errors. | + +Example configuration: + +```yaml +options: + "@azure-tools/typespec-rust": + emitter-output-dir: "{project-root}/clients/rust" + crate-name: "my-service-client" + crate-version: "0.1.0" +``` + ## JavaScript Client Emitter Example ### Step 1: Install Dependencies @@ -241,6 +268,46 @@ Run the following command to generate the C# client: tsp compile {path to main.tsp}/main.tsp ``` +## Rust Client Emitter Example + +### Step 1: Install Dependencies + +Add the following dependencies to your `package.json` file: + +```json +"dependencies": { + "@azure-tools/typespec-rust": "^0.41.0" +} +``` + +Run the following command to install the dependencies: + +```bash +tsp install +``` + +### Step 2: Update Configuration + +Update your `tspconfig.yaml` file with the following configuration: + +```yaml +emit: + - "@azure-tools/typespec-rust" +options: + "@azure-tools/typespec-rust": + emitter-output-dir: "{project-root}/clients/rust" + crate-name: "my-service-client" + crate-version: "0.1.0" +``` + +### Step 3: Generate Client + +Run the following command to generate the Rust client: + +```bash +tsp compile {path to main.tsp}/main.tsp +``` + ## Running Language-Specific Emitters in CLI @@ -255,6 +322,7 @@ tsp compile {path to main.tsp}/main.tsp - "@typespec/http-client-java" - "@typespec/http-client-python" - "@typespec/http-client-js" + - "@azure-tools/typespec-rust" options: "@typespec/http-client-csharp": emitter-output-dir: "{project-root}/clients/dotnet" @@ -264,6 +332,10 @@ tsp compile {path to main.tsp}/main.tsp emitter-output-dir: "{project-root}/clients/python" "@typespec/http-client-js": emitter-output-dir: "{project-root}/clients/javascript" + "@azure-tools/typespec-rust": + emitter-output-dir: "{project-root}/clients/rust" + crate-name: "my-service-client" + crate-version: "0.1.0" ``` 3. Once the package.json and tspconfig.yaml files are updated, you need to install all required dependencies by running the following command in the project root: @@ -290,5 +362,6 @@ tsp compile {path to main.tsp}/main.tsp - [TypeSpec Python emitter library](https://github.com/microsoft/typespec/blob/main/packages/http-client-python/README.md) - [TypeSpec Java emitter library](https://github.com/microsoft/typespec/blob/main/packages/http-client-java/README.md) - [TypeSpec JS emitter library](https://github.com/Azure/autorest.typescript/blob/main/packages/typespec-ts/README.md) +- [TypeSpec Rust emitter library](https://github.com/Azure/typespec-rust/blob/main/packages/typespec-rust/README.md)