Skip to content

Trying to use an enum as a Query parameter causes a panic #1244

@blinsay

Description

@blinsay

I've got an enum as part of my API and tried to use it as a Query type, and immediately got a panic from dropshot while generating the API. I expected this to work, since it looks like PaginationParams and WhichParams are enums and there's no warnings in the docs.

Here's a minimal repro:

use dropshot::HttpError;
use dropshot::HttpResponseOk;
use dropshot::Query;
use dropshot::RequestContext;
use schemars::JsonSchema;
use serde::Deserialize;

fn main() {
    let description = example_api_mod::stub_api_description().unwrap();
    let openapi = description.openapi("example", "0.1.0".parse().unwrap());

    openapi.write(&mut std::io::stdout().lock()).unwrap();
}

#[derive(Deserialize, JsonSchema)]
#[serde(tag = "type")]
enum QueryParamEnum {
    Foo(String),
    Bar { n: usize },
}

#[dropshot::api_description]
trait ExampleApi {
    type Context;

    #[endpoint {
        method = GET,
        path = "/hello",
    }]
    async fn do_stuff(
        ctx: RequestContext<Self::Context>,
        query: Query<QueryParamEnum>,
    ) -> Result<HttpResponseOk<()>, HttpError>;
}

The panic dumps the schema for QueryParamEnum and suggests wrapping it in a struct:

thread 'main' panicked at /Users/benl/.cargo/registry/src/index.crates.io-6f17d22bba15001f/dropshot-0.15.1/src/schema_util.rs:35:13:
while generating schema for QueryParamEnum (parameters): invalid type: {
  "title": "QueryParamEnum",
  "oneOf": [
    {
      "type": [
        "object",
        "string"
...
}
(hint: this appears to be an enum, which needs to be wrapped in a struct)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

If I try to wrap everything in a struct like the error message suggests I do, I still get a panic.

#[derive(Deserialize, JsonSchema)]
struct QueryParam {
    inner: QueryParamEnum,
}

// snip

    #[endpoint {
        method = GET,
        path = "/hello",
    }]
    async fn do_stuff(
        ctx: RequestContext<Self::Context>,
        query: Query<QueryParam>,
    ) -> Result<HttpResponseOk<()>, HttpError>;
thread 'main' panicked at src/main.rs:9:63:
called `Result::unwrap()` on an `Err` value: ApiDescriptionBuildErrors { errors: [ApiDescriptionRegisterError { operation_id: "do_stuff", message: "for endpoint do_stuff the parameter 'inner' must have a scalar type" }] }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions