Skip to content

Support a group of responses having different types across status codes, emitting an enum - #1422

Open
requiel20 wants to merge 1 commit into
oxidecomputer:mainfrom
requiel20:response-enum-for-multiple-types
Open

Support a group of responses having different types across status codes, emitting an enum#1422
requiel20 wants to merge 1 commit into
oxidecomputer:mainfrom
requiel20:response-enum-for-multiple-types

Conversation

@requiel20

@requiel20 requiel20 commented Sep 9, 2026

Copy link
Copy Markdown

Closes #344. Also fixes the reports in #693, #950 and #1155.

A group carrying more than one type now generates an enum with a variant
per status code. The enums live in a response module, one submodule per operation,
so an operation that varies both halves reads as response::get_ready::Success
and response::get_ready::Error.

A group of one type still names that type directly, so no existing golden file changes
and no generated crate anywhere is affected.

Generated code:

  pub mod response {
      pub mod get_ready {
          pub enum Error {
              Status500(types::Err),
              Status503(types::Readiness),
          }
      }
  }

  pub async fn get_ready<'a>(
      &'a self,
  ) -> Result<ResponseValue<types::Readiness>, Error<response::get_ready::Error>>

Usage:

  use progenitor_client::Error;

  match client.get_ready().await {
      Ok(ready) => {
          let readiness: types::Readiness = ready.into_inner();
          println!("ready: {}", readiness.ok);
      }
      Err(Error::ErrorResponse(response)) => {
          let status = response.status();
          match response.into_inner() {
              response::get_ready::Error::Status503(readiness) => {
                  println!("not ready ({status}): ok={}", readiness.ok)
              }
              response::get_ready::Error::Status500(err) => {
                  println!("broke ({status}): {}", err.message)
              }
          }
      }
      Err(other) => println!("transport or unexpected status: {other}"),
  }

This PR supersedes #857, by working on its review notes:

  • the generated types are in their own module, in the response::operation_id::Success
    shape suggested there;
  • errors are covered as well as successes;
  • the new concept lives inside extract_responses rather than beside it;
  • there is a test whose generated output is compiled, not only compared.

The last of those needs #1421 first: progenitor-impl/tests/output has not compiled for
months, so on current main the new golden file is checked as text only. This change does
not depend on that one however, strictly speaking.

…es, emitting an enum

Closes oxidecomputer#344. Also fixes the reports in oxidecomputer#693, oxidecomputer#950 and oxidecomputer#1155.

A group carrying more than one type now generates an enum with a variant
per status code. The enums live in a `response` module, one submodule per operation,
so an operation that varies both halves reads as `response::get_ready::Success`
and `response::get_ready::Error`.

A group of one type still names that type directly, so **no existing golden file changes**
and no generated crate anywhere is affected.

This PR supersedes oxidecomputer#857, by working on its review notes:

- the generated types are in their own module, in the `response::operation_id::Success`
  shape suggested there;
- errors are covered as well as successes;
- the new concept lives inside `extract_responses` rather than beside it;
- there is a test whose generated output is compiled, not only compared.

The last of those needs oxidecomputer#1421 first: `progenitor-impl/tests/output` has not compiled for
months, so on current main the new golden file is checked as text only. This change does
not depend on that one however, strictly speaking.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multiple response types not supported

1 participant