Azure / Azure/typespec-rust

Add support for pageable LROs

Open
#683 0 comments 0 reactions 0 assignees View on GitHub
CodeGen Mgmt
Dominant language
Rust
Stars
7
Forks
11
Avg merge
2d 5h
Merged PRs (30d)
5

Description

## Summary

Add support for pageable LROs — operations that are both long-running AND return paginated results. These are rare in ARM but exist in at least three services. In the TCGC SDK, these surface as methods with `kind: 'lropaging'`.

## Current State

The emitter **explicitly skips** `lropaging` methods with a warning (see `src/tcgcadapter/adapter.ts` lines 1369-1378):

```typescript
if (method.kind === 'lropaging') {
// skip Paging LROs for now so that codegen is unblocked
// TODO: https://github.com/Azure/typespec-rust/issues/188
...
continue;
}
```

Issue #188 (LRO support) has been completed and closed, but the pageable LRO skip was left in place. The emitter already has full support for both `pageable` methods (returning `Pager`) and `lro` methods (returning `Poller`) independently — this feature combines them.

## Affected Services

Grepping through the Go ARM SDKs, the following contain pageable LROs:

### 1. armappservice (Microsoft.Web)
- **`EnvironmentsClient.BeginChangeVnet`** — Move an App Service Environment to a different VNET. Returns `Poller[Pager[ChangeVnetResponse]]`.
- **`EnvironmentsClient.BeginResume`** — Resume an App Service Environment. Returns `Poller[Pager[ResumeResponse]]`.
- **`EnvironmentsClient.BeginSuspend`** — Suspend an App Service Environment. Returns `Poller[Pager[SuspendResponse]]`.
- TypeSpec: `specification/web/resource-manager/Microsoft.Web/AppService/AppServiceEnvironmentResource.tsp`
- The `changeVnet`, `resume`, and `suspend` operations use `DiagnosticsOps` routed operations with LRO + list semantics.

### 2. armnetwork (Microsoft.Network)
- Various operations that are long-running and return paginated lists of resources (exact operations to be confirmed from TypeSpec specs).
- TypeSpec: `specification/network/resource-manager/Microsoft.Network/`

### 3. armorbital (Microsoft.Orbital)
- Similar pattern to network — pageable LRO operations.
- TypeSpec: `specification/orbital/resource-manager/Microsoft.Orbital/`

## Rust API Design

In the Go SDK, pageable LROs are typed as `*runtime.Poller[*runtime.Pager[T]]`. The Rust equivalent should follow a similar composition:

```rust
// Option A: Nested generic — Poller wraps Pager
pub async fn begin_change_vnet(&self, ...) -> Result>>

// Option B: Dedicated PageablePoller type
pub async fn begin_change_vnet(&self, ...) -> Result>
```

The polling phase completes the LRO. Once the LRO completes, the result is iterable as pages via the inner `Pager`. The exact API shape should be consistent with the `azure_core` Rust crate's `Poller` and `Pager` types.

## Implementation Plan

### Phase 1: Code Model

1. **Add `LroPagingMethod` to `src/codemodel/client.ts`**
- New interface combining `LroMethod` and `PageableMethod` properties:
- `kind: 'lropaging'`
- LRO fields: `finalResultStrategy`, `statusMonitor`
- Pageable fields: `pageableItemName`, `nextLink`, `continuationToken`
- Add corresponding class implementation

2. **Add `LroPaging` return type to `src/codemodel/types.ts`**
- Compose `Poller>` return type

### Phase 2: Adapter

3. **Handle `lropaging` in `src/tcgcadapter/adapter.ts`** (lines 1369-1378)
- Replace the skip/warning with actual adaptation logic
- Extract both LRO metadata (final result strategy, status monitor) and paging metadata (nextLink, page item name)
- Create `LroPagingMethod` instances

### Phase 3: Code Generation

4. **Generate pageable LRO method bodies in `src/codegen/clients.ts`**
- Combine the polling closure logic (from `getLroMethodBody()`) with the paging handler logic (from `getPageableMethodBody()`)
- The LRO poller should resolve to a `Pager` that handles pagination of the final result

### Phase 4: Testing

5. **Create a minimal TypeSpec test under `test/tsp/`**
- Define a simple pageable LRO operation for unit testing
- Verify the generated Rust code compiles

6. **Verify against real ARM specs**
- Test code generation against the `Microsoft.Web/AppService` TypeSpec specs
- Ensure the generated `BeginChangeVnet`, `BeginResume`, `BeginSuspend` methods compile and have the correct signatures

### Phase 5: Validation

7. **Full CI validation**
- `pnpm build` — emitter compiles
- `pnpm test` — unit tests pass
- `pnpm run tspcompile` — regenerate test crates
- `cargo build` — generated Rust crates compile
- `cargo clippy` — no warnings

## Dependencies

- LRO support (issue #188) ✅ completed
- Pageable support ✅ completed
- May depend on `azure_core` Rust crate updates if `Poller>` composition isn't already supported

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.