Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions website/src/content/current-sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,13 @@ const sidebar: SidebarItem[] = [
[],
"preview",
),
createLibraryReferenceStructure(
"emitters/clients/http-client-rust",
"Rust",
false,
[],
"preview",
),
],
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -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<T>` instead of the default `Pager<T>`. A `PageIterator<T>` asynchronously yields individual items across all pages, while a `Pager<T>` 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. |
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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

<Tabs>
<TabItem label="In a spec" default>

```bash
npm install @azure-tools/typespec-rust
```

</TabItem>
<TabItem label="In a library" default>

```bash
npm install --save-peer @azure-tools/typespec-rust
```

</TabItem>
</Tabs>

## Emitter usage

[See documentation](./emitter.md)

## Supported decorators

[See documentation](./decorators.md)
87 changes: 80 additions & 7 deletions website/src/content/docs/docs/emitters/clients/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -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:

Expand All @@ -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",
}
```

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

<Steps>
Expand All @@ -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"
Expand All @@ -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:
Expand All @@ -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)

</Aside>
Loading