ProbablyClem/utoipauto

Components lack full module paths

MiniaczQ opened this issue · 13 comments

Hello, we're trying out this crate for a college assignment involving a backend server.

We've setup the project to use just utoipa then proceeded to replace the declarations with this crate's macro.
The derived components seem to lack the module path, so instead of crate::routing::api::audio::DeleteSamplesRequest the macro generates just DeleteSamplesRequest. And so it asks us to import it, as well as every other missing model.
This is the error
image

Intuition is telling me, the components should be added with the full paths. Not sure if this is a problem by design.

There are few examples where paths are added to the macro, but I don't think that's our use case. Do let me know if I'm doing something wrong.

Hey,
Components are added by full path...
Can you show me the file structure of your project ?

Here's the code with just utoipa:
bpiktel/2023z-sdp#2

I fixed it in 0.1.3

image

Just tested 0.1.3, still incorrect.

I expanded the macro, the paths aren't being added to the component elements:
image

nor path elements

Isn't your path this ?
image
There's a unit test that should cover the case.

It seems that you have your paths both in src/routing/api//audio.rs and in main.rs ...

There's a unit test that should cover the case.

I ran a search and there seems to be no such test on this repository 🫤
Edit:
It has a slightly different name so the search didn't show up :p

It seems that you have your paths both in src/routing/api//audio.rs and in main.rs ...

mod routing;
mod services;

use routing::main_route;
use services::{
    database::{files::FileStorage, surreal::SurrealDb},
    runner::run,
};

use crate::services::{app::AppState, config::setup_config, tracing::setup_tracing};

#[tokio::main]
async fn main() {
    let config = setup_config();
    setup_tracing(&config.tracing);
    let auth_keys = (&config.auth_keys).try_into().expect("Missing PEMs");
    let surreal_db = SurrealDb::setup(&config.surreal_db)
        .await
        .expect("Failed to setup SurrealDb");
    let file_storage = FileStorage::setup(&config.file_storage)
        .await
        .expect("Failed to setup FileStorage");
    let state = AppState {
        auth_keys,
        surreal_db,
        file_storage,
    };
    run(config.app.url, main_route(&config).with_state(state)).await;
}

#[cfg(test)]
mod tests {
    use std::fs::OpenOptions;

    use crate::routing;
    use crate::services;
    use utoipa::OpenApi;
    use utoipauto::utoipauto;

    #[test]
    fn make_openapi_json() {
        #[utoipauto] // <===== Error here
        #[derive(OpenApi)]
        #[openapi(
            tags(
                (name = "todo", description = "chghckgj")
            )
        )]
        pub struct ApiDoc;
        let file = OpenOptions::new()
            .write(true)
            .truncate(true)
            .create(true)
            .open("openapi.json")
            .unwrap();
        serde_json::to_writer_pretty(file, &ApiDoc::openapi()).unwrap();
    }
}

This is the entire main.rs, I'm not sure I understand the path issue, but all I do is mod the module that contains the models, I don't use it nor define another struct with the same name as models.

Here, I posted this exact version on a branch for easier testing:
https://github.com/bpiktel/2023z-sdp/tree/utoipauto

Yeah you don't need to use since it's supposed to add the function with the full path

#[utoipa::path(
    post,
    path = "/audio/delete",
    responses(
        (status = 200, description = "Delete listed audio samples successfully", body = DeleteSamplesRequest)
    )
)]
async fn delete_audio( <==== Add pub
    audio_repo: AudioRepository,
    _: Claims,
    ValidatedJson(data): ValidatedJson<DeleteSamplesRequest>,
) -> ResponseType<()> {
    let Ok(_) = audio_repo
        .delete_samples(data.ids)
        .await
        .map_err(|e| error!({error = ?e}, "Encountered an error while deleting a sample"))
    else {
        return ResponseType::Status(StatusCode::INTERNAL_SERVER_ERROR);
    };

    ResponseType::Status(StatusCode::OK)
}

I think the issue is that your handler are not public, which means they can't be used outside ou the module

I've made everything that could be public public, doesn't seem to fix it :(

@ProbablyClem can't this issue be closed?

Or why it is marked as invalid and still remains open?

I left it opened because it's not really fixed...
@MiniaczQ We're closing this issue for inactivity but feel free to open it again if the issue remains.