ProbablyClem / utoipauto

Rust Macros to automate the addition of Paths/Schemas to Utoipa crate, simulating Reflection during the compilation phase
Apache License 2.0
108 stars 10 forks source link

Detecting `ToSchema` fails when behind a `cfg_attr` flag #13

Open tedbennett opened 7 months ago

tedbennett commented 7 months ago

Hi! :wave:

I'm playing around with this crate and ran into an issue where schemas (and I'm guessing paths) aren't detected when behind a cfg_attr flag. E.g: Works:

#[derive(ToSchema)]
struct Todo {
  // ...
}

Doesn't work:

#[cfg_attr(feature = "openapi", derive(ToSchema))]
struct Todo {
  // ...
}

Essentially, my use case is to only generate the OpenAPI spec when writing it to a file in my CI step, and I don't want to have to compile all my utoipa macros when running the webserver normally.

Thanks for the library, it's really nice!

tedbennett commented 7 months ago

Oh, thinking about this more, since the detection is done via the macro I'm guessing it might run before the cfg flags are applied? And you probably wouldn't want to include Schemas behind said feature flag if they're switched off...

ProbablyClem commented 6 months ago

From this https://stackoverflow.com/a/42551386, it seems that #[cfg_attr(feature = "openapi", derive(ToSchema))] is the same as derive(ToSchema) if the openapi flag is enabled. So it seems that procedural macros are executed before feature flags, and I can't really find a way to see which feature flags are enabled from within the macro.

There is probably a solution to this but I don't know how to fix it yet...

DenuxPlays commented 5 months ago

Also: ToSchema detection fails also when the struct is contained in a macro. (For example bitflags macro)

RemiBardon commented 4 months ago

I was about to submit an issue for this… guess I'm stuck like you đŸ˜• Has anyone found a solution/workaround?

RemiBardon commented 4 months ago

It doesn't look good… I found https://github.com/rust-lang/rust-analyzer/issues/13360 which mentions no solution…

DenuxPlays commented 3 weeks ago

I think this is doable.

cfg_attr flag

We could add the struct like this:

#[cfg(feature = "feature name")]
path::to::struct

to the OpenApi macro.

for macros like bitflags

I think this is quit unsovable because we cannot expand the macro.

ProbablyClem commented 3 weeks ago

This could work to remove a struct from the spec, but this wouldn't remove the compile time cost of the macro I believe...

DenuxPlays commented 3 weeks ago

No the macro would take the same amount of time and resources regardless if a feature is active or not.

But AFAIK we cannot get whether a feature is activated or not from a macro. So this would be inevitable.